1. 程式人生 > >SSM中shiro的基本使用

SSM中shiro的基本使用

throws splay 自己的 tro 跳轉 uri see url nat

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配置文件中所寫的“異常處理”類攔截,然後轉向相應頁面。

SSM中shiro的基本使用