Spring集成Shiro及简单实用

导入依赖

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.9</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.6.RELEASE</version>
        </dependency>
        

Spring-Context配置相应Bean

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="login.html"/>
        <property name="unauthorizedUrl" value="403.html"/>
        <property name="filterChainDefinitions">
            <value> 
                /login.html = anon  <!--anon的代表是不要认证的-->
                /subLogin = anon
                /* = authc		<!--anon的代表是要认证的,一般放最后-->
            </value>
        </property>
    </bean>

    <!--创建SecurityManager-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="realm" />
    </bean>

    <bean id="realm" class="com.ay.shiro.realm.CustomRealm">
       <!-- <property name="credentialsMatcher" ref="credentialsMatcher"/> -->
    </bean>

    <!--<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <property name="hashAlgorithmName" value="md5" />
        <property name="hashIterations" value="1" />

    </bean>-->

密码如果使用MD5加密需要credentialsMatcher

自定义Realm

一般 user,role,permission是存在数据库的3+2表,自定义Realm通过持久层读取相关需要验证的信息。

public class CustomRealm extends AuthorizingRealm {
    {
        super.setName("customRealm");
    }

    @Resource
    private UserDao userDao;

    @Override  //授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();
        //模拟获取roles permission
        Set<String> roles = getRolesByUsername(username);
        Set<String> permission = getPermissionByUsername(username);

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(roles);
        simpleAuthorizationInfo.setStringPermissions(permission);
        return simpleAuthorizationInfo;
    }

    private Set<String> getPermissionByUsername(String username) {
        List<String> permission = userDao.getPermissionByUsername(username);
        if(permission == null){
            return  null;
        }
        Set<String> set = new HashSet<>(permission);
        return set;
    }

    private Set<String> getRolesByUsername(String username) {
        List<String> roles = userDao.getRolesByUsername(username);
        if(roles == null){
            return  null;
        }
        Set<String> set = new HashSet<>(roles);
        return set;
    }

    @Override //认证  主体提交认证后的处理
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String) authenticationToken.getPrincipal();
        //模拟从数据库获取密码
        String password = getPasswordByUsername(username);
        if(password == null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                username,password,"customRealm");
        //对原密码要进行加盐,数据库存的也是要进行加盐加密的密码
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(username));
        return authenticationInfo;
    }

    private String getPasswordByUsername(String username) {
        User user = userDao.getUserByUsername(username);
        if(user != null){
            return user.getPassword();
        }
        return null;
    }

    public static void main(String[] args){
        Md5Hash md5Hash = new Md5Hash("123456","Ay");
        System.out.println(md5Hash.toString());
    }
}

控制层

得到主体,生成token,进行认证和授权。

@RequestMapping(value = "/subLogin",method = RequestMethod.POST,
    produces = "application/json;charset=utf-8")
    @ResponseBody
    public String subLogin(User user){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword());
        try {
            subject.login(token);
//            subject.checkRole("admin");
//            subject.checkPermission("user:select");
        }catch (Exception e){
            return e.getMessage();
        }
        return "登录成功";
    }

通过注释进行授权

<!--shiro注释-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

bean配置

<!--开启shiro注释-->
    <aop:config proxy-target-class="true"/>
    <bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>

示例方法
已认证的用户需要admin才能访问

@RequiresRoles("admin")
    @RequestMapping(value = "/testRole",method = RequestMethod.GET)
    @ResponseBody
    public String testRole(){
        return "testRole success";
    }

猜你喜欢

转载自blog.csdn.net/weixin_41768073/article/details/83826098