enhance:更正Shiro文章中的一些错误。
This commit is contained in:
parent
3ea954c059
commit
d4b083c023
|
@ -107,19 +107,13 @@ Token是一个用于承载用于用户认证信息的容器,常用的Token只
|
|||
```xml
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>${shiro.spring.version}</version>
|
||||
</dependency>
|
||||
<!-- 如果是基于Web的应用,还需要加入以下依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-web</artifactId>
|
||||
<artifactId>shiro-spring-boot-starter</artifactId>
|
||||
<version>${shiro.spring.version}</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
!!! info ""
|
||||
在本文进行编写的时候,Shiro-Spring的版本是1.8.0。
|
||||
在本文进行编写的时候,`shiro-spring-boot-starter`的版本是1.8.0。你可能在Shiro的官方网站上看到了Shiro与Spring整合的说明,但是请注意,那片说明是针对Shiro与Spring应用整合的,而不是用于Spring Boot应用的。另外,在网上许多教程与介绍中,都建议使用`shiro-spring-boot-web-starter`,但是通过对Shiro源码的查看,`shiro-spring-boot-web-starter`已经合并进了`shiro-spring-boot-starter`,所以直接选用最短的那个就好。
|
||||
|
||||
### 认证与授权功能流程
|
||||
|
||||
|
@ -132,6 +126,9 @@ Token是一个用于承载用于用户认证信息的容器,常用的Token只
|
|||
!!! info ""
|
||||
其实对于用户认证处理最核心的就是,只要调用`subject.login(token)`时不抛出任何异常,那么用户就已经被系统认证通过了,可以在之后的操作中通过获取`Subject`实例来得到用户的相关信息。
|
||||
|
||||
!!! caution ""
|
||||
需要注意的是,`shiro-spring-boot-starter`中对于Bean的引用大部分都是通过Bean名称的,所以如果在运行Spring应用的时候,提示缺少再买一个名称的Bean,那么可以检查一下应用中的Shiro配置,看看是不是已经定义了相应类型的Bean,但是没有使用Shiro需求的名字。这样的话可以直接给应用中的Bean重新起一个名字即可。
|
||||
|
||||
### Shiro配置
|
||||
|
||||
对Shiro的配置,主要是配置Shiro的处理流程,通过定义其中的关键部件,使上图中的流程完全打通。在加入其他的功能类之前,可以首先先在项目中添加一个仅有基本功能的配置类。
|
||||
|
@ -249,7 +246,7 @@ public List<Realm> authenticationRealms() {
|
|||
|
||||
```java
|
||||
@Component
|
||||
public class MultiRealmsSecurityManager extends DefaultSecurityManager {
|
||||
public class MultiRealmsSecurityManager extends DefaultWebSecurityManager {
|
||||
|
||||
public MultiRealmsSecurityManager(
|
||||
SubjectDAO subjectDAO,
|
||||
|
@ -270,6 +267,9 @@ public class MultiRealmsSecurityManager extends DefaultSecurityManager {
|
|||
}
|
||||
```
|
||||
|
||||
!!! info ""
|
||||
因为所构建的应用是一个提供Web服务的应用,所以需要继承`DefaultWebSecurityManager`来提供对于Web的安全控制。
|
||||
|
||||
#### 构建对用户名与密码的验证
|
||||
|
||||
首先假设应用中的用户表结构是如下面这样定义的。
|
||||
|
@ -321,6 +321,11 @@ public class Member {
|
|||
public class UsernameRealm extends AuthoringRealm {
|
||||
private final MemberRepository memberRepository;
|
||||
|
||||
@PostConstruct
|
||||
private void initRealm() {
|
||||
super.setCredentialsMatcher(new HashedCredentialsMatcher("SHA-512"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(AuthenticationToken token) {
|
||||
return token instanceof UsernamePasswordToken;
|
||||
|
@ -368,7 +373,7 @@ public class TokenStore {
|
|||
@Column(nullable = false)
|
||||
LocalDateTime expiresAt;
|
||||
|
||||
@OneToOne(targetEntity = Member.class, fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
|
||||
@OneToOne(targetEntity = Member.class, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
|
||||
@JoinColumn(name = "mid")
|
||||
Member member;
|
||||
}
|
||||
|
@ -383,6 +388,11 @@ public class TokenRealm extends AuthorizingRealm {
|
|||
private final MemberRepository memberRepository;
|
||||
private final TokenStoreRepository storeRepository;
|
||||
|
||||
@PostConstruct
|
||||
private void initRealm() {
|
||||
super.setCredentialsMatcher(new SimpleCredentialsMatcher());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(AuthorizationToken token) {
|
||||
return token instanceof BearerToken;
|
||||
|
@ -439,7 +449,7 @@ public class WebShiroConfig {
|
|||
SecurityUtils.setSecurityManager(this.securityManager);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Bean(name = "shiroFilterFactoryBean")
|
||||
@Autowired
|
||||
public ShiroFilterFactoryBean shiroFilterFactory(
|
||||
ShiroFilterChainDefainition filterChainDefinition
|
||||
|
@ -447,10 +457,6 @@ public class WebShiroConfig {
|
|||
var filterFactory = new ShiroFilterFactoryBean();
|
||||
filterFactory.setSecurityManager(this.securityManager);
|
||||
|
||||
Map<String, Filter> filters = new HashMap<>();
|
||||
filters.put("bearer", bearerFilter());
|
||||
filterFactory.setFilters(filters);
|
||||
|
||||
filterFactory.setLoginUrl("/login");
|
||||
filterFactory.setFilterChainDefinitionMap(filterChainDefinition.getFilterChainMap());
|
||||
return filterFactory;
|
||||
|
@ -464,13 +470,29 @@ public class WebShiroConfig {
|
|||
chainDefinition.addPathDefinition("/logout", "logout");
|
||||
chainDefinition.addPathDefinition("/login", "anon");
|
||||
// 要求所有需要携带用户令牌的请求都必须经过BearerHttpAuthenticationFilter
|
||||
chainDefinition.addPathDefinition("/**", "bearer");
|
||||
chainDefinition.addPathDefinition("/**", "authcBearer");
|
||||
|
||||
return chainDefinition;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 集成Shiro后常见错误的处理
|
||||
|
||||
##### 所有路径都报404错误
|
||||
|
||||
出现这种情况的原因是`shiro-spring-boot-starter`在进行自动配置的时候,没有正确的配置`DefaultAdvisorAutoProxyCreator`的Bean,所以只需要在Shiro的配置类中加入这个Bean即可,代码可以仿照以下Bean实例化代码添加。
|
||||
|
||||
```java
|
||||
@Bean
|
||||
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
|
||||
var creator = new DefaultAdvisorAutoProxyCreator();
|
||||
creator.setUsePrefix(true);
|
||||
|
||||
return creator;
|
||||
}
|
||||
```
|
||||
|
||||
### 处理用户登录
|
||||
|
||||
用户登录主要是一个收集用户提供的认证信息并进行校验的过程,在Shiro提供的Realm加持下,处理用户登录的过程被简化成了只需要组装`AuthenticationToken`,不必再次实现认证信息的校验的过程。以下是一个登录Controller的示例。
|
||||
|
|
Loading…
Reference in New Issue
Block a user