zoukankan      html  css  js  c++  java
  • SSM中shiro的基本使用

    shiro

      用以网站的授权和认证

    配置:

    一、shiro基本配置文件

      所用的entity user和role 实体类

     1 @Entity
     2 @Table(name="USER_P")
     3 @DynamicInsert(value=true)
     4 @DynamicUpdate(value=true)
     5 public class User extends BaseEntity {
     6     @Id
     7     @Column(name="USER_ID")
     8     @GeneratedValue(generator="system-assigned")
     9     @GenericGenerator(name="system-assigned",strategy="assigned")
    10     private String id;
    11     
    12     @JsonManagedReference
    13     //@ManyToOne(cascade= {CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH},fetch=FetchType.EAGER)
    14     @ManyToOne
    15     @JoinColumn(name="DEPT_ID")
    16     private Dept dept;
    17     
    18     @OneToOne(cascade=CascadeType.ALL)
    19     //@OneToOne
    20     @JoinColumn(name="USER_ID")
    21     private Userinfo userinfo;
    22     
    23     @JsonBackReference
    24     @ManyToMany(cascade= {CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH},fetch=FetchType.EAGER)
    25     //@ManyToMany
    26     @JoinTable(name="ROLE_USER_P",joinColumns= {@JoinColumn(name="USER_ID",referencedColumnName="USER_ID")},
    27     inverseJoinColumns= {@JoinColumn(name="ROLE_ID",referencedColumnName="ROLE_ID")})
    28     @OrderBy("ORDER_NO")
    29     private Set<Role> roles= new HashSet<>();        //用户对应角色
    30     
    31     @Column(name="USER_NAME")
    32     private String userName;
    33     
    34     @Column(name="PASSWORD")
    35     private String password;
    36     
    37     @Column(name="STATE")
    38     private Integer state;
    39 
    40     //getter和setter方法
    41 }
    42 
    43 @Entity
    44 @Table(name="ROLE_P")
    45 @DynamicInsert(true)
    46 @DynamicUpdate(true)
    47 public class Role extends BaseEntity {
    48     @Id
    49     @Column(name="ROLE_ID")
    50     @GeneratedValue(generator="system-uuid")
    51     @GenericGenerator(name="system-uuid",strategy="org.hibernate.id.UUIDGenerator")
    52     private String id;        //角色ID
    53     
    54     @JsonBackReference
    55     @ManyToMany(cascade= {CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH},fetch=FetchType.EAGER)
    56     @JoinTable(name="ROLE_USER_P",joinColumns= {@JoinColumn(name="ROLE_ID",referencedColumnName="ROLE_ID")},
    57     inverseJoinColumns= {@JoinColumn(name="USER_ID",referencedColumnName="USER_ID")})
    58     private Set<User> users = new HashSet<>(0);        //用户对应角色
    59     
    60     @Column(name="NAME")
    61     private String name;        //角色名称
    62     
    63     @Column(name="REMARK")
    64     private String remark;        //备注
    65     
    66     @Column(name="ORDER_NO")
    67     private Integer orderNo;    //排序号
    68 
    69     //getter和setter方法
    70 }
    View Code

      一个新的xml文件 beans-shiro.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
            http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
        <!-- 配置Spring整合shiro -->
        <!-- 配置安全管理器 -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <!-- 自定义realm域对象 -->
            <property name="realm" ref="authRealm" />
        </bean>
        
        <!-- 编写realm类 -->
        <bean id="authRealm" class="cn.ssm.trading.shiro.AuthRealm" />
        
        <!-- Spring框架整合Shiro框架 -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <!-- 安全管理器 -->
            <property name="securityManager" ref="securityManager" />
            <!-- 登陆页面 -->
            <property name="loginUrl" value="/login.jsp" />
            <!-- 认证成功跳转页面 -->
            <!-- <property name="successUrl" value="/index.jsp" /> -->
            <!-- 无权限跳转页面 -->
            <property name="unauthorizedUrl" value="/html/unauthorized.jsp" />
            <!-- 定义访问规则 -->
            <property name="filterChainDefinitions">
                <value>
                    <!-- anon:不用认证, authc:需认证 -->
                    /login.jsp = anon
                    /login* = anon
                    /logout* = anon
                    /css/** = anon
                    /img/** = anon
                    /js/** = anon
                    /images/** = anon
                    /js/** = anon
                    /json/** = anon
                    /make/** = anon
                    /skin/** = anon
                    /static/** = anon
                    /resource/** = anon
                    /html/** = authc
                    /** = authc
                    /*.* = authc
                </value>
            </property>
        </bean>
    </beans>

    在spring配置文件中(配置了aop、事务管理、数据源的那个文件)加上:

           <!-- 导入shiro配置文件 -->  

      <import resource="classpath:beans-shiro.xml"/>

      <!-- 产生shiro核心控制器的方式,使用cglib生成代理 -->
      <aop:aspectj-autoproxy proxy-target-class="true" />

    二、shiro过滤器 配置在web.xml中 放在springmvc分发器前

        <!-- Shiro核心控制器,表示由spring管理生命周期 -->
        <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            <init-param>
                <param-name>targetFilterLifecycle</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>shiroFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

    三、开启注解

    在springmvc的配置文件中(配置了视图解析器的那个文件)加入:

        <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
        
        <!-- 生成代理,通过代理进行控制 -->
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
            <property name="proxyTargetClass" value="true" />
        </bean>
        
        <!-- 安全管理器 -->
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager" />
        </bean>
        <!-- 异常处理(无权限) -->
        <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <props>
                    <prop key="org.apache.shiro.authz.UnauthorizedException">
                        /unauthorized.jsp
                    </prop>
                    <prop key="org.apache.shiro.authz.UnauthenticatedException">
                        redirect:/login.jsp
                    </prop>
                </props>
            </property>
            <property name="defaultErrorView" value="/error.jsp" />
            <property name="exceptionAttribute" value="ex" />
        </bean>

    四、认证 授权方法 编写AuthRealm类(即'域' )

     1    public class AuthRealm extends AuthorizingRealm{ 
    2
    3 @Resource 4 UserService userService; 5 6 @Override 7 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { 8 System.out.println("授权方法"); 9 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 10 User user = (User) arg0.getPrimaryPrincipal();   //获得当前登陆的用户 11 Set<Role> roles = user.getRoles();          //当前用户拥有的角色,根据自己的entity 12 //指示当前用户能访问的资源 13 for(Role role : roles) { 14 info.addStringPermission(role.getName()); 15 } 16 return info; 17 } 18 19 @Override 20 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { 21 System.out.println("认证方法"); 22 UsernamePasswordToken token =(UsernamePasswordToken)arg0; 23 final String username = token.getUsername(); 24
           //fibd的查询条件 25 Specification<User> spec = new Specification<User>() { 26 @Override 27 public Predicate toPredicate(Root<User> arg0, CriteriaQuery<?> arg1, CriteriaBuilder arg2) { 28 // TODO 自动生成的方法存根 29 return arg2.equal(arg0.get("userName").as(String.class), username); 30 } 31 }; 32 List<User> userList = userService.find(spec);      //jpa,即在数据中找到满足条件的用户 33 if(userList!=null&&userList.size()>0) { 34 User user = userList.get(0); 35 //参数1:登陆的用户,参数2:密码,参数3:区分realm 36 return new SimpleAuthenticationInfo(user,user.getPassword(),getName()); 37 } 38 39 return null; 40 } 41 }

    五、登陆认证方法(在controller中)

     1     @RequestMapping("/security/login.action")
     2     public String login(String username,String password) {
     9         Subject subject = SecurityUtils.getSubject();
    10         UsernamePasswordToken token = new UsernamePasswordToken(username,password);    //新建令牌
    11         try {
    12             subject.login(token);                                  //会去调用认证方法16             return "redirect:/index.jsp";
    17         }catch(Exception e) {19             return "redirect:/login.jsp";                             //认证失败会抛出异常
    20         }
    21     }

    六、授权

    1、使用标签

      现在页面中引入shiro标签 <%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>

      例如:<shiro:hasPermission name='权限名'> 有该权限这里的内容才会显示 </shiro:hasPermission>

      其中name属性:由于我们在上面的授权方法中加入当前用户所拥有的权限了 “info.addStringPermission(role.getName());”,所以此时会去判断name所写的权限名,当前用户是否拥有;

      更多标签请自行查阅文档;

    2、使用注解

    在controller相应的方法上加上

    1     @RequestMapping("/list.action")
    2     @RequiresPermissions("权限名")
    3     public String list(Model model) {
    4             ....
    5     }  

    当访问该方法时,会去判断当前用户是否拥有该权限;

    若无则抛出异常,会被上面spring-mvc配置文件中所写的“异常处理”类拦截,然后转向相应页面。

  • 相关阅读:
    如何提高英阅读英文技术资料
    如何阅读英语文章
    vijosP1223麦森数
    vijosP1359 Superprime
    vijosP1319 数列
    vijosP1447 开关灯泡
    vijosP1164 曹冲养猪
    vijosP1016 北京2008的挂钟
    洛谷P1457 城堡(The Castle)
    洛谷P1294 高手去散步
  • 原文地址:https://www.cnblogs.com/Drajun/p/10325407.html
Copyright © 2011-2022 走看看