springboot shiro jwt实现权限控制
时间: 2023-08-17 14:11:46 浏览: 161
Spring Boot 是一个用于创建独立的、基于生产级别的 Spring 应用程序的框架,而 Shiro 是一个强大且易于使用的 Java 安全框架,用于身份认证、授权和会话管理。JWT (JSON Web Token) 是一种用于表示声明的安全令牌。
要在 Spring Boot 中使用 Shiro 和 JWT 实现权限控制,可以按照以下步骤进行操作:
1. 添加依赖:在 Maven 或 Gradle 文件中添加 Spring Boot、Shiro 和 JWT 的依赖项。
2. 配置 Shiro:创建一个 Shiro 的配置类,配置 Shiro 的安全管理器、自定义 Realm、会话管理器等。
3. 实现 JWT 认证过滤器:创建一个 JWT 认证过滤器,用于解析请求中的 JWT 并进行用户认证。
4. 实现自定义 Realm:创建一个自定义 Realm,用于从数据库或其他数据源中获取用户信息和权限信息。
5. 定义用户认证和权限注解:根据需要,可以定义一些自定义的注解,用于标识需要进行身份认证或权限控制的方法或接口。
6. 编写控制器:编写控制器类来处理请求,根据用户的认证状态和权限信息来决定是否允许访问资源。
以上是一个大致的步骤,具体实现的细节可以根据你的需求和项目结构进行调整。这里只是提供了一个基本的思路,希望对你有所帮助。如果你需要更详细的代码示例,可以提供更具体的需求和项目背景,我可以给你提供更多的帮助。
相关问题
springboot shiro jwt jession
### Spring Boot 集成 Shiro 和 JWT 进行身份验证
在现代Web应用程序中,无状态的身份验证方法越来越受欢迎。相比于传统的基于会话(session)的方式,使用JSON Web Tokens (JWT) 可以为API提供更安全、可扩展的身份验证方案[^1]。
#### 实现思路
为了实现在Spring Boot项目里通过Shiro和JWT来进行用户认证而非依赖于服务器端存储的Session对象,主要涉及以下几个方面的配置:
- **创建自定义Realm**: 继承`AuthorizingRealm`, 负责处理用户的登录请求以及权限校验逻辑。
- **Token解析与验证**: 编写工具类来完成对传入HTTP头中的token字符串解码并检验其有效性。
- **过滤器设置**: 定义一个继承自`OncePerRequestFilter` 的filter,在每次接收到客户端发来的请求之前先检查是否存在有效的jwt token.
- **替换默认SubjectFactory**: 修改shiro的核心行为使其不再尝试从HttpSession获取subject而是直接利用Jwt.
下面给出具体代码片段用于说明上述概念:
```java
// 自定义 Realm 类
public class JwtRealm extends AuthorizingRealm {
@Override
public boolean supports(AuthenticationToken token){
return token instanceof JwtToken;
}
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){}
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)throws AuthenticationException{}
}
```
```java
// Token 工具类
@Component
public final class JwtUtil {
private static final String SECRET_KEY = "your_secret_key";
/**
* 创建 jwt
*/
public String createToken(String username){}
/**
* 解析 jwt 并返回其中包含的信息
*/
public Claims parseToken(String token){}
}
```
```java
// Filter 类
public class JwtFilter extends OncePerRequestFilter{
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {}
}
```
```java
@Configuration
public class ShiroConfig {
@Bean(name="securityManager")
public DefaultWebSecurityManager getManager(){
DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
// 设置realm.
manager.setRealm(jwtRealm());
// 替换掉原有的 SubjectFactory
manager.setSubjectFactory(new StatelessDefaultSubjectFactory());
return manager;
}
}
```
以上就是关于如何在Spring Boot 应用程序内集成了Apache Shiro 和 JSON Web Tokens 来替代传统 Session 做身份验证的一个简单介绍[^2].
springboot shiro jwt实列源码
### Spring Boot与Shiro及JWT集成实例
#### 项目结构概述
为了实现Spring Boot与Apache Shiro以及JSON Web Token (JWT) 的集成,通常需要构建一个安全框架来管理认证和授权。下面是一个简化版的项目结构:
```
src/main/java/com/example/demo/
├── config/
│ ├── SecurityConfig.java
│ └── JwtTokenFilter.java
├── controller/
│ └── UserController.java
└── service/
└── UserServiceImpl.java
```
#### 配置类 `SecurityConfig.java`
此配置文件用于设置Shiro的安全策略并初始化必要的Bean。
```java
@Configuration
public class SecurityConfig {
@Autowired
private Realm realm;
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(realm);
return manager;
}
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 设置未登录跳转页面
shiroFilterFactoryBean.setLoginUrl("/unauthorized");
HashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// 对所有请求应用Jwt过滤器
filterChainDefinitionMap.put("/**", "jwt");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
```
#### 自定义领域 `JwtRealm.java`
该类实现了`AuthorizingRealm`接口,并重写了两个核心方法:`doGetAuthenticationInfo()` 和 `doGetAuthorizationInfo()` 来处理身份验证和权限控制逻辑。
```java
public class JwtRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 获取当前用户的用户名
String username = (String)principals.getPrimaryPrincipal();
// 基于用户名查询角色/权限信息...
Set<String> roles = userService.findRolesByUsername(username);
Set<String> permissions = userService.findPermissionsByUsername(username);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(permissions);
info.setRoles(roles);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken)token;
String username = upToken.getUsername();
User user = userService.findByUsername(username);
if(user == null || !new BCryptPasswordEncoder().matches(upToken.getPassword(), user.getPassword())) {
throw new UnknownAccountException("Invalid credentials.");
}
byte[] salt = Encodes.decodeHex(user.getSalt());
return new SimpleAuthenticationInfo(
username,
user.getPassword(),
ByteSource.Util.bytes(salt),
getName()
);
}
}
```
#### JWT令牌过滤器 `JwtTokenFilter.java`
此类负责解析HTTP头中的Bearer Tokens,并将其转换成Shiro可以理解的身份凭证对象。
```java
@Component
public class JwtTokenFilter implements Filter {
@Autowired
private JwtUtil jwtUtil;
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
String authHeader = request.getHeader("Authorization");
if(authHeader != null && authHeader.startsWith("Bearer ")) {
try{
Claims claims = jwtUtil.parseClaims(authHeader.substring(7));
Subject subject = SecurityUtils.getSubject();
if(subject.isAuthenticated()){
chain.doFilter(req,res);
return ;
}
if(jwtUtil.isTokenExpired(claims)){
((HttpServletResponse)response).sendError(HttpServletResponse.SC_UNAUTHORIZED,"Token expired!");
return ;
}
String username = claims.getSubject();
List<SimpleGrantedAuthority> authorities =
Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
UsernamePasswordToken authToken = new UsernamePasswordToken(username,null,authorities.toArray(new GrantedAuthority[0]));
subject.login(authToken);
}catch(Exception e){
logger.error(e.getMessage());
((HttpServletResponse)response).sendError(HttpServletResponse.SC_UNAUTHORIZED,e.getMessage());
return ;
}
}
chain.doFilter(request,response);
}
}
```
上述代码片段展示了如何将Spring Boot、Shiro和JWT结合起来使用[^1]。通过这种方式,可以在保持RESTful API无状态的同时提供强大的安全性保障。
阅读全文
相关推荐













