Shiro 的学习总结

一个简单的shiro应用流程,就是通过Subject来进行认证和授权,而Subject又委托给SecurityManager,然后向SecurityManager注入Realm,从而让SecurityManager能得到合法的用户及其权限进行判断。

Subject :包含 principals(身份)、credentials(凭证)两部分;

SecurityManager :它管理着所有Subject,是Shiro的核心;

Realm :获取安全数据(如用户、角色、权限),即安全数据源;

AuthorizationInfo :为当前登录的用户授予角色和权限;

AuthenticationInfo :身份认证/登录,验证用户是不是拥有相应的身份;

SessionManager :shiro 自己的会话管理容器;

权限认证:

1).基于角色的认证

subject.hasrole(role);  //返回一个boolean
subject.hasroles(arrays.aslist(role1,role2));       //返回一个boolean数组,即每个角色的有无
subject.hasAllroles(arrays.aslist(role1,role2));    //返回一个boolean,即全有或不全有

subject.checkrole(role);    //无返回值,没有此角色报错
subject. checkroles (arrays.aslist(role1,role2));       //无返回值,没有此角色报错
subject. Checkroles (role1,role2);      //无返回值,没有此角色报错

2) 基于权限的认证

subject.ispermitted(权限);    //返回一个boolean
subject.ispermitted(权限1,权限2);   //返回一个boolean数组
subject.ispermittedall(权限1,权限2);    //返回一个boolean,即全有或不全有

shiro 与 spring的整合:

1、首先在web.xml文件中配置前端过滤器:

    <filter>
        <filter-name>shiroFilterfilter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
        <async-supported>trueasync-supported>
        <init-param>
            <param-name>targetFilterLifecycleparam-name>
            <param-value>trueparam-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>shiroFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>

2、在 spring 中配置 shiro


<bean class="com.eaphy.realm.MyRealm" id="myRealm"/>


<bean class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" id="securityManager">
    <property name="realm" ref="myRealm"/>
bean>


<bean class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" id="shiroFilter">
    
    <property name="securityManager" ref="securityManager"/>
    
    <property value="/index.jsp" name="loginUrl"/>
    
    <property value="/unauthor.jsp" name="unauthorizedUrl"/>
    
    <property name="filterChainDefinitions">
        <value> 
            /login=anon //任意用户都可访问
            /admin*=authc //用户必须登录才能访问
            /student=roles[teacher] //需要用户有用teacher权限
        value>
    property>
bean>


<bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor" id="lifecycleBeanPostProcessor"/>


<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
bean>

自定义 realm:

package com.eaphy.realm;


import javax.annotation.Resource;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import com.eaphy.entity.User;
import com.eaphy.service.UserService;

public class MyRealm extends AuthorizingRealm{

    @Resource
    private UserService userService;

    /**
     * 为当限前登录的用户授予角色和权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String userName=(String)principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(userService.getRoles(userName));
        authorizationInfo.setStringPermissions(userService.getPermissions(userName));
        return authorizationInfo;
    }

    /**
     * 验证当前登录的用户
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName=(String)token.getPrincipal();
            User user=userService.getByUserName(userName);
            if(user!=null){
                AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"xx");
                return authcInfo;
            }else{
                return null;                
            }
    }

}

登录代码:

    @RequestMapping("/login")
    public String login(User user,HttpServletRequest request){
        Subject subject=SecurityUtils.getSubject();
        UsernamePasswordToken token=new UsernamePasswordToken(user.getUserName(), user.getPassword());
        try{
            subject.login(token);
            Session session=subject.getSession();
            System.out.println("sessionId:"+session.getId());
            System.out.println("sessionHost:"+session.getHost());
            System.out.println("sessionTimeout:"+session.getTimeout());
            session.setAttribute("info", "session的数据");
            return "redirect:/success.jsp";
        }catch(Exception e){
            e.printStackTrace();
            request.setAttribute("user", user);
            request.setAttribute("errorMsg", "用户名或密码错误!");
            return "index";
        }
    }

你可能感兴趣的:(Shiro)