实用向-shiro+spingboot入门

一 shiro使用

1.1 shiro依赖
<dependency>
   <groupId>org.apache.shiro</groupId>
   <artifactId>shiro-spring</artifactId>
   <version>1.3.2</version>
</dependency>
1.2 shiro配置
package com.xk.mymall.shiro;

import com.xk.mymall.shiro.CustomRealm;
import org.apache.shiro.authc.Authenticator;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
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;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager,Map<String, String> filterChainDefinitionMap) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //1. 自定义安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //2. 自定义过滤器链
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public Map<String, String> filterChainDefinitionMap(){
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        //1.定义哪些请求需要认证
        filterChainDefinitionMap.put("/**", "authc");
        return filterChainDefinitionMap;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
        //1.设置自定义Relam来验证登陆结果
        defaultSecurityManager.setRealm(customRealm());
        return defaultSecurityManager;
    }

    @Bean
    public CustomRealm customRealm() {
        CustomRealm customRealm = new CustomRealm();
        //principle加密
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        hashedCredentialsMatcher.setHashIterations(2);
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
        customRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return customRealm;
    }
}

二 shiro认证

2.1 认证流程

在这里插入图片描述

2.2 自定义Token
package com.nriat.core.shiro;

import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.HostAuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;

public class PhoneToken  extends UsernamePasswordToken {

    private String phoneNumber;
    private String verifyCode;

    @Override
    public Object getPrincipal() {
        return getPhoneNumber();
    }

    @Override
    public Object getCredentials() {
        return getVerifyCode();
    }



    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getVerifyCode() {
        return verifyCode;
    }

    public void setVerifyCode(String verifyCode) {
        this.verifyCode = verifyCode;
    }

    @Override
    public String getHost() {
        return null;
    }
}

2.3 自定义Relam
package com.nriat.shiro;

import com.nriat.core.redis.service.RedisService;
import com.nriat.core.shiro.PhoneToken;
import com.nriat.utils.GlobalParam;
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 org.springframework.beans.factory.annotation.Autowired;

import com.nriat.core.system.model.User;
import com.nriat.core.system.service.UserService;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class PhoneRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;

	@Autowired
	private RedisService redisService;
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		String phoneNumber = (String) principals.getPrimaryPrincipal();

		User user = userService.findByPhoneNumber(phoneNumber);
		if(user!= null){
			SimpleAuthorizationInfo result = new SimpleAuthorizationInfo();
			Set<String> roles = new HashSet<>();
			roles.add(user.getRoleId().toString());
			result.setRoles(roles);
			return result;
		}else{
			return null;
		}
	}

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

		if (token instanceof PhoneToken) {
			String phoneNumber =  (String) token.getPrincipal();
			User userFind = userService.findByPhoneNumber(phoneNumber);
			if (userFind != null) {
				String verifyCode = (String) redisService.get(GlobalParam.Phone_PREFIX_CODE+phoneNumber);
				AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(userFind.getPhoneNumber(), verifyCode, this.getClass().getName());
				return authcInfo;
			} else {		
				return null;
			}
		} else {
			return null;
		}
	}

}

三 shiro鉴权

3.1 注解实现权限控制

shiroConfig中添加以下配置,启动注解

@Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor
            = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

@RequiresAuthentication 验证是否登录

@RequiresRoles 验证是否拥有角色

@RequiresRoles(value = { "1","2","3"},logical= Logical.OR)
value:角色或角色数组
logical:Logical.OR拥有其中一种角色,Logical.AND满足所有角色

@RequiresPermissions 验证是否拥有权限

@RequiresPermissions(value = { "1:read","2:write","3:read"},logical= Logical.AND)
value:权限或权限数组
logical:Logical.OR拥有其中一种权限,Logical.AND满足所有权限
3.2 URL过滤实现权限控制

在过滤器链中配置

@Bean
    public Map<String, String> filterChainDefinitionMap(){
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        //1.定义哪些请求需要认证
        filterChainDefinitionMap.put("/**", "authc");
        return filterChainDefinitionMap;
    }
anon: /admins/**=anon 没有参数,表示可以匿名使用。
authc: /admins/user/**=authc 表示需要认证(登录)才能使用,没有参数
roles:/admins/user/**=roles[admin],参数可以写多个,每个参数通过才算通过。
perms:/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗
3.3 代码块实现权限控制
try {
    Subject subject = SecurityUtils.getSubject();
    if(subject.hasRole("user")){
        //TODO
    }
} catch (AuthorizationException e) {
    e.printStackTrace();
}

四 shiro其他操作

4.1 获取用户登陆信息

在登陆成功以后,设置session

subject.login(token);
//将用户信息放入session
if(subject.isAuthenticated()){
	Session session = subject.getSession();
	session.setAttribute(CacheUtils.SESSION_USER,findByPhoneNumber(phoneNumber));
}

封装获取user方法

public static Long getCurrentUserId(){
	Subject subject = SecurityUtils.getSubject();
	Session session =  subject.getSession();
	User user = (User) session.getAttribute(CacheUtils.SESSION_USER);
	return user.getId();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Shiro是一个强大的Java安全框架,可以帮助开发者轻松地实现身份认证、授权管理和会话管理等安全功能。而Spring Boot是一个用于简化Spring应用开发的框架,它提供了一些开箱即用的特性,使得开发者可以快速搭建一个基于Spring的应用。 将Shiro与Spring Boot结合使用,可以让我们更方便地使用Shiro的各种安全特性。Shiro提供了一些与Spring集成的组件,例如我们可以通过使用Shiro的注解来实现权限控制,同时也可以利用Spring的依赖注入特性来处理Shiro的一些配置。 在Spring Boot中使用Shiro主要有以下步骤:首先,我们需要在Spring Boot的配置文件中配置Shiro的相关信息,例如Realm(用于认证和授权的数据源)、filter(用于拦截和处理请求)等。接着,我们需要创建一个自定义的Realm来实现具体的认证和授权逻辑。然后,我们可以使用Shiro提供的注解在Controller层进行权限控制,例如@RequiresAuthentication用于要求用户进行身份认证,@RequiresRoles用于要求用户具有某个角色等等。最后,在前端页面或者API中,我们可以通过Shiro提供的标签或者API来展示或者处理与用户权限相关的信息。 总结起来,Shiro和Spring Boot的结合为我们提供了一种便捷的方式来实现应用的安全功能。我们可以通过Shiro来管理用户的身份认证和权限控制,通过Spring Boot来简化应用的开发过程。这样,我们可以更加专注于业务逻辑的实现,同时也提高了应用的安全性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值