shiro的使用1 简单的认证


最近在重构,有空学了一个简单的安全框架shiro,资料比较少,在百度和google上能搜到的中文我看过了,剩下的时间有空会研究下官网的文章和查看下源码,

简单的分享一些学习过程;

1,简单的一些概念上的认知

2,使用认证的基本流程

3,shiro集成spring完成简单的认证流程,已实现

1 建一个maven的web项目,引入依赖
  springmvc的的依赖
     
            org.springframework
            spring-webmvc
            3.2.0.RELEASE
       

shiro跟spring集成的插件
 
            org.apache.shiro
            shiro-spring
            1.2.3
       
2 配置web.xml
指出spring容器的配置文件位置

        contextConfigLocation
        classpath*:context_config.xml
   

指出spring在web容器中的代号
   
        webAppRootKey
        wechatSystem
   

初始化spring的容器
   
        org.springframework.web.context.ContextLoaderListener
   

spring mvc的分发器
   
          admin
          org.springframework.web.servlet.DispatcherServlet
       
            contextConfigLocation
            classpath*:admin-dispatcher-servlet.xml
       

        1
    

    
          admin
          /
    

spring跟shiro集成的过滤代理
 
        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
       
            targetFilterLifecycle
            true
       

   

   
        shiroFilter
        /admin/*
   

   
   
        characterEncoding
        org.springframework.web.filter.CharacterEncodingFilter
       
            encoding
            UTF-8
       

       
            forceEncoding
            true
       

   

   
        characterEncoding
        /*
   
3 配置shiroFilter实例
 
   
       
       
       
       
       
           
               
               
           

       

       
           
               
               
           

       

       
           
                /admin/login=anon
                /admin/validCode=anon
                /user/**=authc
                /role/**=authc
                /permission/**=authc
                /**=authc
           

       

   

   
   
    
       
   

    



4 开发跟shiro交互的RealM,一般把权限信息放到db中
package com.util;

import com.domain.User;
import com.domain.UserDto;
import com.google.common.base.Strings;
import com.service.UserDtoService;
import com.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
* User: cutter.li
* Date: 2014/6/19 0019
* Time: 15:24
* 备注: 自定义的mysql数据源
*/
@Component
public class MysqlJdbcRealM extends JdbcRealm {

    @Resource
    private UserService userService;

    //登录认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String username = String.valueOf(usernamePasswordToken.getUsername());
        User user = userService.findByUserName(username);
        AuthenticationInfo authenticationInfo = null;
        if (null != user) {
            String password = new String(usernamePasswordToken.getPassword());
            if (password.equals(user.getPassword())) {
                authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
            }
        }
        return authenticationInfo;
    }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String username = (String) principals.getPrimaryPrincipal();
        if (!Strings.isNullOrEmpty(username)) {
            SimpleAuthorizationInfo authenticationInfo = new SimpleAuthorizationInfo();
            authenticationInfo.setRoles(userService.findRolesStr(username));
            authenticationInfo.setStringPermissions(userService.findPermissionsStr(username));
            return authenticationInfo;
        }
        return null;

    }
}
 
5 简单的登录页面,功能测试


6 controller的实现:
 @RequestMapping(value = "login", method = RequestMethod.POST)
    public ResponseEntity loginSubmit(String username, String password, String vcode, HttpServletRequest request) {
        message.setSuccess();
        validateLogin(message, username, password, vcode);
        try {
//            String code = request.getSession().getAttribute(AppConstant.KAPTCHA_SESSION_KEY).toString();
//            if (!vcode.equalsIgnoreCase(code)) {
//                message.setCode(AppConstant.VALIDCODE_ERROR);
//                message.setMsg("验证码错误");
//            }
            if (message.isSuccess()) {

                Subject subject = SecurityUtils.getSubject();
                subject.login(new UsernamePasswordToken(username, password));

                if (subject.isAuthenticated()) {
                        message.setMsg("登录成功");
                } else {
                    message.setCode(AppConstant.USERNAME_NOTEXIST);
                    message.setMsg("用户名/密码错误");
                }
            }
        }catch (AuthenticationException ex){
            message.setCode(AppConstant.USERNAME_NOTEXIST);
            message.setMsg("用户名/密码错误");
            ex.printStackTrace();
        }
        finally {
            return new ResponseEntity(message, HttpStatus.OK);
        }

    }
 
7 指定认证的策略和多数据源
   
   
       
       
       
       
       
           
               
               
           

       

       
           
               
               
           

       

       
           
                /admin/login=anon
                /admin/validCode=anon
                /user/**=authc
                /role/**=authc
                /permission/**=authc
                /**=authc