springboot项目使用 shiro 实现接口授权具体实现
时间: 2023-12-16 18:04:04 浏览: 38
使用Shiro实现接口授权的具体实现步骤如下:
1. 引入Shiro和Spring-boot-starter依赖:
```xml
<dependencies>
<!-- Shiro依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.8.0</version>
</dependency>
<!-- Spring-boot-starter依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
```
2. 配置Shiro的Filter和Realm:
```java
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
filterFactoryBean.setSecurityManager(securityManager);
filterFactoryBean.setLoginUrl("/login"); // 设置未登录时跳转的URL
filterFactoryBean.setUnauthorizedUrl("/unauthorized"); // 设置未授权时跳转的URL
// 配置拦截规则
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon"); // 登录接口放行
filterChainDefinitionMap.put("/logout", "logout"); // 注销接口放行
filterChainDefinitionMap.put("/**", "authc"); // 其他接口全部拦截,需要认证后访问
filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return filterFactoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
return securityManager;
}
@Bean
public Realm realm() {
// 自定义Realm实现
return new MyRealm();
}
}
```
3. 自定义Realm实现授权逻辑:
```java
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 获取当前用户信息
String username = (String) principals.getPrimaryPrincipal();
// 查询用户角色和权限信息
Set<String> roles = new HashSet<>();
Set<String> permissions = new HashSet<>();
// TODO: 查询用户角色和权限信息
// roles.add("admin");
// permissions.add("user:list");
// 封装角色和权限信息
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(roles);
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 获取用户输入的用户名和密码
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// TODO: 验证用户名和密码是否正确
// if (!"admin".equals(username)) {
// throw new UnknownAccountException("用户名不存在!");
// }
// if (!"admin".equals(password)) {
// throw new IncorrectCredentialsException("密码错误!");
// }
// 封装用户认证信息
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
return authenticationInfo;
}
}
```
4. 在Controller中使用注解实现接口授权:
```java
@RestController
@RequestMapping("/user")
public class UserController {
@RequiresPermissions("user:list")
@GetMapping("/list")
public String list() {
return "用户列表";
}
@RequiresPermissions("user:add")
@PostMapping("/add")
public String add() {
return "添加用户";
}
}
```
在Controller方法上使用@RequiresPermissions注解,指定需要的权限,如果当前用户没有该权限,则会抛出AuthorizationException异常,可以在异常处理器中统一处理。