SpringBoot+Shiro整合思路

数据库+MD5+Salt认证功能

之前完成了用户md5+salt的用户注册流程

现在就完成以下认证的功能

认证的数据依旧是来自于数据库中的
这里就需要修改一下自定义realm中的认证实现换成数据库而不是写死的功能

需要现在UserDAO增加一个方法

1
User findByUserName(String username);

在UserDAOMapper.xml中添加对应的select方法

1
2
3
4
<select id="findByUserName" parameterType="String" resultType="User">
select id,username,password,salt from t_user
where username = #{username}
</select>

同样的在业务层UserService添加方法
1
2
//根据用户名查询业务的方法
User findByUserName(String username);

UserServiceImpl中的实现也要加上
1
2
3
4
@Override
public User findByUserName(String username) {
return userDAO.findByUserName(username);
}

接着就是去修改realm方法啦,但是并没有业务对象,现在业务对象是由工厂去进行注入的

所以就建一个工具类ApplicationContextUtils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.ceit.springboot_jsp_shiro.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextUtils implements ApplicationContextAware {
private static ApplicationContext context;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}

//根据bean名字获取工厂中指定bean对象
public static Object getBean(String beanName){
return context.getBean(beanName);
}
}

接下来就可以把自定义realm中写死的数据改为数据库连接了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.ceit.springboot_jsp_shiro.shiro.realms;

import com.ceit.springboot_jsp_shiro.entity.User;
import com.ceit.springboot_jsp_shiro.service.UserService;
import com.ceit.springboot_jsp_shiro.utils.ApplicationContextUtils;
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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.util.ObjectUtils;

//自定义Realm
public class CustomerRealm extends AuthorizingRealm {

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("=====================================");

//根据身份信息
String principal = (String)authenticationToken.getPrincipal();
//在工厂中获取service对象
UserService userService = (UserService) ApplicationContextUtils.getBean("userService");

User user = userService.findByUserName(principal);

if(!ObjectUtils.isEmpty(user)){
return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), ByteSource.Util.bytes(user.getSalt()),this.getName());
}
return null;
}
}

但是这样还不行 因为我们的数据进行了md5和加盐的操作 所以必须还要修改一下凭证校验匹配器
在ShiroConfig中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.ceit.springboot_jsp_shiro.config;

import com.ceit.springboot_jsp_shiro.shiro.realms.CustomerRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
* 用来整合Shiro框架的配置类
*/
@Configuration
public class ShiroConfig {
//1. 创建shiroFilter
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

//给filter设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

//配置系统受限资源
//配置系统公共资源
Map<String,String> map = new HashMap<String,String>();
map.put("/user/login","anon"); //anon 设置为公共资源
map.put("/user/register","anon");
map.put("/register.jsp","anon");
map.put("/**","authc"); //authc 请求这个资源需要认证和授权

//默认认证界面路径
shiroFilterFactoryBean.setLoginUrl("/login.jsp");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);


return shiroFilterFactoryBean;
}

//2. 创建安全管理器
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getRealm") Realm realm){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();

//给安全管理器设置realm
defaultWebSecurityManager.setRealm(realm);

return defaultWebSecurityManager;
}

//3. 创建自定义realm
@Bean
public Realm getRealm(){
CustomerRealm customerRealm = new CustomerRealm();
//修改凭证校验匹配器
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//设置加密方式为md5
credentialsMatcher.setHashAlgorithmName("MD5");
//设置散列次数
credentialsMatcher.setHashIterations(1024);
customerRealm.setCredentialsMatcher(credentialsMatcher);
return customerRealm;
}
}

这样就完成了数据库+MD5+Salt的认证功能了