Shiro的应用之认证拦挡

    Shiro是一个平安开发框架,它把零碎的平安认证等相干性能抽取进去,升高了零碎的开发成本。        

一 Shiro实现认证拦挡

    步骤: 1 零碎调用subject的login办法将用户信息传递给securityManager          2 securityManager将认证操作委托给Authenticator          3 Authenticator将用户输出的身份信息发送给Realm          4 Realm拜访数据库获取用户信息并将信息封装并返回          5 Authenticator对封装的信息进行身份认证          


输出用户信息后登陆到零碎界面


1.须要的依赖
<dependency>     <groupId>org.apache.shiro</groupId>     <artifactId>shiro-spring</artifactId>     <version>1.5.3</version></dependency>
2. Shiro的外围配置对象

在springboot中没有为咱们主动配置shiro,所以要手动配置

  • 首先创立一个配置类:SpringShiroConfig类;
  • 而后在配置类中增加SecurityManager接口对象;
  • 在配置类中增加一个ShiroFilterFactoryBean对象;通过此对象实现对匿名拜访和认证拜访
  • 代码如下:
package com.py.pj.common.config;import java.util.LinkedHashMap;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.realm.Realm;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @author WL * @version 创立工夫:2020-9-19 13:24:57 * @Description Shiro的外围配置对象 * @Configuration 此注解形容的类是一个配置对象,此对象会交给spring解决 * @Bean 此注解形容的类会被交给spring解决,由spring为咱们创建对象 */@Configurationpublic class SpringShiroConfig {        @Bean    public SecurityManager securityManager(Realm realm) {        DefaultWebSecurityManager dsm = new DefaultWebSecurityManager();        dsm.setRealm(realm);        return dsm;    }    @Bean    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {        ShiroFilterFactoryBean sffBean = new ShiroFilterFactoryBean();        sffBean.setSecurityManager(securityManager);          //  设置登录界面url        sffBean.setLoginUrl("/doLogin");                LinkedHashMap<String, String> map = new LinkedHashMap<>();        map.put("/bower_components/**", "anon");        map.put("/modules/**", "anon");        map.put("/dist/**", "anon");        map.put("/plugins/**", "anon");        // 用户登录界面容许匿名拜访        map.put("/user/doLogin", "anon");        //  退出登陆        map.put("/doLogout", "logout");                // 除了动态资源,其余的都要认证        map.put("/**", "authc");        sffBean.setFilterChainDefinitionMap(map);        return sffBean;    }}
3.业务模块实现
    本模块的业务在realm模块中实现
  • 3.1 依据用户名搜寻用户信息

在SysUserMapper中创立findUserByUsername(String username)办法

SysUser findUserByUsername(String username);mapper映射文件中<select id="findUserByUsername" resultType="com.py.pj.sys.entity.SysUser">    select * from sys_users where username=#{username}</select>
  • 3.2 创立realm业务层
package com.py.pj.sys.realm;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.LockedAccountException;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UnknownAccountException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authc.credential.CredentialsMatcher;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.py.pj.sys.dao.SysUserMapper;import com.py.pj.sys.entity.SysUser;/** * @author WL * @version 创立工夫:2020-9-19 14:15:12 * @Description 受权realm继承认证,所以蕴含认证和受权性能 */@Servicepublic class ShiroUserRealm extends AuthorizingRealm {    @Autowired    private SysUserMapper sysUserMapper;    /**     * 设置凭证匹配器匹配规定     */    @Override    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {        // 创立凭证匹配器对象        HashedCredentialsMatcher hcm = new HashedCredentialsMatcher();        // 设置加密算法,与用户明码加密算法放弃始终        hcm.setHashAlgorithmName("MD5");        // 设置加密次数        hcm.setHashIterations(1);        super.setCredentialsMatcher(hcm);    }    /**     * 受权     */    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {        // TODO Auto-generated method stub        return null;    }    /**     * 重写认证 token 是从客户端传来的用户的账号信息     */    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {        // 1.获取用户输出的用户名        UsernamePasswordToken UToken = (UsernamePasswordToken) token;        String username = UToken.getUsername();        // 2.基于用户名查用户信息        SysUser user = sysUserMapper.findUserByUsername(username);        // 3.判断用户是否存在、是否禁用        if (user == null) {            throw new UnknownAccountException();        }        if (user.getValid() == 0) {            throw new LockedAccountException();        }        // 4.封装用户信息        // 盐值是ByteSource格局的所以要转换        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());        System.out.println(user.getPassword());        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, // principal (身份)                user.getPassword(), // hashedCredentials                credentialsSalt, // credentialsSalt                getName());// realName        return info;    }}
  • 3.3 controller层
        @RequestMapping("doLogin")    public JsonResult doLogin(String username,String password) {        //    每个用户都是一个subject对象        Subject subject = SecurityUtils.getSubject();        //    对用户进行封装        UsernamePasswordToken token = new UsernamePasswordToken(username,password);        //    token被传给securityManager;securityManager在传递给Authentication;Authentication再传给realm,从数据库中获取并封装用户信息        subject.login(token);        return new JsonResult("OK");    }

至此,借助Shiro实现了用户的登陆认证性能。