shiro集成SSM

1.导入POM文件


    org.apache.shiro
    shiro-core
    1.4.0


    org.apache.shiro
    shiro-web
    1.4.0


    org.apache.shiro
    shiro-ehcache
    1.4.0


    org.apache.shiro
    shiro-spring
    1.4.0

2. web.xml



    Archetype Created Web Application

    
        contextConfigLocation
        classpath:spring-*.xml
    
    
        org.springframework.web.context.ContextLoaderListener
    

    
        springmvc
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            classpath:springmvc-context.xml
        
        1
    
    
        springmvc
        /
    
    <--! DelegatingFilterProxy 作用是自动到 Spring容器查找名字为 shiroFilter(filter-name)
    的 bean 并把所有 Filter的操作委托给它 -->
    
        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
        
            targetFilterLifecycle
            true
        
    
    
        shiroFilter
        /*
    

    
        encoding
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            utf-8
        
    
    
        encoding
        /*
    

注:DelegatingFilterProxy的filter-name要和spring-shiro中的shiroFilterFactoryBean中的id相同,否则报错,或者使用以下方法(在DelegatingFilterProxy中加入


        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
        
            targetFilterLifecycle
            true
        
        
             targetBeanName
             name
        
    
    
        shiroFilter
        /*
    

此时spring-shiro中的shiroFilterFactoryBean中的id和param-value相同,即name

3.spring-shiro.xml




    

    
        
        
        
        
            
                
                
            

        
    

    
    
        
            
            
            
        

    

    
        
        
        
        

        
        

       

    

    
    
        
        
        
    
    
    
        
    

    
        
            
                
                
                
                
            
        

    

    
        
            
                
                
            
        
    

    
    
    
        
    
    
        
    

    
    

    


4.Controller

    @RequestMapping("/doLogin")
    public String doLogin(String username, String password) {
        System.out.println("doLogin.............");
        Subject subject= SecurityUtils.getSubject();


        if(!subject.isAuthenticated()){
            UsernamePasswordToken token=new UsernamePasswordToken(username,password,true);
            try {
                subject.login(token);
            } catch (AuthenticationException e) {
                System.out.println("认证失败。");
            }
        }
        return "redirect:success";
    }

5.realm

public class FirstRealm extends AuthorizingRealm{

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken uptoken=(UsernamePasswordToken) token;
        String username = uptoken.getUsername();
        String credentials=null;

        if("zhangsan".equals(username)){
            credentials="2a0d136ceacafe198ea64ac09daaf1b6";
        }else if("lisi".equals(username)){
            credentials = "8c702ae443795331c91cfab48f3f3833";
        }
        ByteSource byteSource=new ByteSource.Util().bytes(username);
        AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, credentials, byteSource, getName());
       // new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
        return authenticationInfo;
    }

    public static void main(String[] args) {
        String hashAlgorithmName = "MD5";
        Object credentials = "123456";
        Object salt = ByteSource.Util.bytes("lisi");;
        int hashIterations = 1024;

        Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
        System.out.println(result);
    }
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        System.out.println("FirstRealm..2222.........");
        Object primaryPrincipal = principals.getPrimaryPrincipal();

        Set roles = new HashSet<>();
        if("zhangsan".equals(primaryPrincipal)){
            roles.add("user");
            roles.add("vip");
        }else if("abc".equals(primaryPrincipal)){
            roles.add("user");
        }
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRoles(roles);

        return simpleAuthorizationInfo;
    }
}
public class SecondRealm extends AuthorizingRealm{

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken uptoken=(UsernamePasswordToken) token;

        String username = uptoken.getUsername();
        String credentials=null;

        if("abc".equals(username)){
            credentials="31420b87dd2e42f39d7dc7bdc3a7ee12e4053de8";
        }else if("qwe".equals(username)){
            credentials = "466c492b84308fb956c6d1acf4301743cbc19037";
        }
        ByteSource byteSource=new ByteSource.Util().bytes(username);
        AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, credentials, byteSource, getName());
       // new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
        return authenticationInfo;
    }

    public static void main(String[] args) {
        String hashAlgorithmName = "SHA1";
        Object credentials = "123";
        Object salt = ByteSource.Util.bytes("qwe");;
        int hashIterations = 1024;

        Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
        System.out.println(result);
    }
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        System.out.println("secondRealm...。。。..........");
        Object primaryPrincipal = principals.getPrimaryPrincipal();

        Set roles = new HashSet<>();
        if("zhangsan".equals(primaryPrincipal)){
            roles.add("admin");
        }else if("abc".equals(primaryPrincipal)){
            roles.add("admin");
        }
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roles);


        return simpleAuthorizationInfo;
    }
}
  • 自定义的realm继承AuthorizingRealm就可以实现认证和授权方法,AuthorizingRealm继承自AuthenticatingRealm,AuthenticatingRealm中有doGetAuthenticationInfo方法,AuthorizingRealm中有doGetAuthorizationInfo
  • realm的认证策略:

    • FirstSuccessfulStrategy:只要有一个 Realm 验证成功即可,只返回第一个 Realm 身份验证成功的认证信息,其他的忽略;
    • AtLeastOneSuccessfulStrategy:只要有一个Realm验证成功即可,和FirstSuccessfulStrategy 不同,将返回所有Realm身份验证成功的认证信息;(默认策略)
    • AllSuccessfulStrategy:所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败了。
  • 因为缓存:先去第一个realm寻找role,如果第一个realm有放入当前页面的权限就不继续访问下一个realm,当继续访问其他页面而第一个realm没有放入当前页面的role,则去第二个realm寻找。(不会重复访问,不配置缓存就会重复访问)
  • filterChainDefinitionMap工厂(filterChainDefinitionMap和filterChainDefinitions只能存在一个)
public class FilterChainDefinitionMapFactory {

    public LinkedHashMap buildFilterChainDefinitionMap(){
        LinkedHashMap map = new LinkedHashMap<>();
        
        map.put("/doLogin", "anon");
        map.put("/logout", "logout");
        map.put("/admin", "authc,roles[admin]");
        map.put("/user", "roles[user]");
        map.put("/test", "user");
        map.put("/vip", "user");
        map.put("/success", "user");
        map.put("/**", "authc");
        return map;
    }
}

rememberMe功能如果要认证才可以操作的的除了加权限还要加authc 例如:map.put("/admin", "authc,roles[admin]");否则可以通过记住我直接访问/admin

shiro权限注解

  • @RequiresAuthentication:表示当前Subject已经通过login进行了身份验证;即 Subject. isAuthenticated() 返回 true
  • @RequiresUser:表示当前 Subject 已经身份验证或者通过记住我登录的。
  • @RequiresGuest:表示当前Subject没有身份验证或通过记住我登录过,即是游客身份。
  • @RequiresRoles(value={“admin”, “user”}, logical= Logical.AND):表示当前 Subject 需要角色 admin 和user,@RequiresRoles(value={“admin”, “user”}, logical= Logical.OR):表示当前 Subject 需要角色 admin 或user中的其中一个
  • @RequiresPermissions (value={“user:a”, “user:b”}, logical= Logical.OR):表示当前 Subject 需要权限 user:a 或user:b。
@RequiresRoles(value = {"admin","vip"},logical = Logical.AND)
    @RequestMapping(value = {"/testAnnotation2"})
    public String testAnnotation2(){
        System.out.println("testAnnotation2222。");
        return "success";
    }

如果要在Controller层使用注解,要在springmvc.xml中添加



    


    

如果要在service中使用,在spring-shiro中即可

httpsession和SecurityUtils.getSubject().getSession()可以互相改,可以在service调用session

session也有会话监听器用于监听会话创建、过期及停止事件onStart,onStop,onexpiration

shiro登录验证码

你可能感兴趣的:(shiro,ssm,spring)