专注Java领域技术
我们一直在努力

一篇博客帮你搞定 Spring Security 使用数据库认证

原文始发于:一篇博客帮你搞定 Spring Security 使用数据库认证

一、前期准备

(1)pom.xml

		<dependency> 			<groupId>org.springframework.security</groupId> 			<artifactId>spring-security-web</artifactId> 			<version>${spring.security.version}</version> 		</dependency> 		<dependency> 			<groupId>org.springframework.security</groupId> 			<artifactId>spring-security-config</artifactId> 			<version>${spring.security.version}</version> 		</dependency> 

(2)web.xml

<context-param> 	<param-name>contextConfigLocation</param-name> 	<param-value>classpath:spring-security.xml</param-value> </context-param> <listener> 	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> 	<filter-name>springSecurityFilterChain</filter-name> 	<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> 	<filter-name>springSecurityFilterChain</filter-name> 	<url-pattern>/*</url-pattern> </filter-mapping> 

(3)spring-security.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:security="http://www.springframework.org/schema/security"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans.xsd     http://www.springframework.org/schema/security     http://www.springframework.org/schema/security/spring-security.xsd">      <!-- 配置不拦截的资源 -->     <security:http pattern="/login.jsp" security="none"/>     <security:http pattern="/failer.jsp" security="none"/>     <security:http pattern="/css/**" security="none"/>     <security:http pattern="/img/**" security="none"/>     <security:http pattern="/plugins/**" security="none"/>     <!--     	配置具体的规则     	auto-config="true"	不用自己编写登录的页面,框架提供默认登录页面     	use-expressions="false"	是否使用SPEL表达式(没学习过)     -->     <security:http auto-config="true" use-expressions="false">         <!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_USER的角色" -->         <security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>          <!-- 定义跳转的具体的页面 -->         <security:form-login                 login-page="/login.jsp"                 login-processing-url="/login.do"                 default-target-url="/index.jsp"                 authentication-failure-url="/failer.jsp"                 authentication-success-forward-url="/pages/main.jsp"         />          <!-- 关闭跨域请求 -->         <security:csrf disabled="true"/>         <!-- 退出 -->         <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />      </security:http>      <!-- 切换成数据库中的用户名和密码 -->     <security:authentication-manager>         <security:authentication-provider user-service-ref="userService">             <!-- 配置加密的方式             <security:password-encoder ref="passwordEncoder"/>-->         </security:authentication-provider>     </security:authentication-manager>      <!-- 配置加密类 -->     <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>      </beans> 

注意
一篇博客帮你搞定 Spring Security 使用数据库认证
这里Access指定的角色好像是固定的,只能写成“ROLE_USER”和“ROLE_ADMIN”,写成其他的不好使,原因有待补充

二、Spring Security 使用流程分析

一篇博客帮你搞定 Spring Security 使用数据库认证
(1)spring-security.xml 定义登录的一些操作,比如登录页面、路径,对哪些操作执行具体的认证操作-,以及加密操作
比如这里就指定了认证的具体操作 userService
一篇博客帮你搞定 Spring Security 使用数据库认证
这里定义加密的方式,可以实现用户密码加密操作:具体使用可参考
一篇博客帮你搞定 Spring Security 使用数据库认证

(2)userService 需要调用 dao 根据用户名密码完成认证操作,这里介绍通过 UserDetails、UserDetailsService 完成操作

  • UserDetailsService,通过继承使用,获取认证的用户信息
public interface UserDetailsService { 	UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; } 
  • UserDetails是一个接口,我们可以认为UserDetails作用是于封装当前进行认证的用户信息,但由于其是一个接口,所以我们可以对其进行实现,也可以使用Spring Security提供的一个UserDetails的实现类User来完成操作

UserDetails 接口的方法:

public interface UserDetails extends Serializable { 	Collection<? extends GrantedAuthority> getAuthorities(); 	String getPassword(); 	String getUsername(); 	boolean isAccountNonExpired(); 	boolean isAccountNonLocked(); 	boolean isCredentialsNonExpired(); 	boolean isEnabled(); } 

User 类的部分代码:

public class User implements UserDetails, CredentialsContainer { 	private String password; 	private final String username; 	private final Set<GrantedAuthority> authorities; 	private final boolean accountNonExpired; //帐户是否过期 	private final boolean accountNonLocked; //帐户是否锁定 	private final boolean credentialsNonExpired; //认证是否过期 	private final boolean enabled; //帐户是否可用

三、具体使用

(1)UserService 接口

public interface UserService extends UserDetailsService { } 

(2)UserServiceImpl.java

@Service("userService") public class UserServiceImpl implements UserService {     @Autowired     private UserDao userDao;      @Override     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {         UserInfo userInfo = null;          try {             userInfo = userDao.findByUsername(username);         } catch (Exception e) {             e.printStackTrace();         }          User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), userInfo.getStatus() == 0 ? false : true,                 true, true, true, getAuthority(userInfo.getRoles()));         return user;     }      /**      * 作用就是返回一个List集合,集合中装入的是角色描述      * @param roles      * @return      */     public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) {          List<SimpleGrantedAuthority> list = new ArrayList<>();         for (Role role : roles) {             list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));         }         return list;     } } 

四、注意

(1)"{noop}" + userInfo.getPassword():{noop}之所以添加,是因为这里用户是通过数据库进行添加的,密码是明文显示,必须要加
一篇博客帮你搞定 Spring Security 使用数据库认证
当通过用户界面添加用户时,可以对密码进行加密处理,这样就不用加 “{noop}”了
一篇博客帮你搞定 Spring Security 使用数据库认证
此时对应再封装成 User 对象时:
一篇博客帮你搞定 Spring Security 使用数据库认证

此时的具体操作可参考

(2)对获取的用户角色进行拼接
一篇博客帮你搞定 Spring Security 使用数据库认证
主要用来对应 spring-security 中设置的权限角色:
一篇博客帮你搞定 Spring Security 使用数据库认证
(3)数据库中的用户表信息含有一个状态值:
一篇博客帮你搞定 Spring Security 使用数据库认证
查看 UserDetails 中的 User 对象:
一篇博客帮你搞定 Spring Security 使用数据库认证
发现除了用户名、密码、认证信息之外,它还有一些其他属性,什么是否能用,是否锁定之类的,所以用户表这里的状态值就对应着要封装成 User 中的 Boolean enabled

所以,如果不考虑这些其他的值,封装方式为:

一篇博客帮你搞定 Spring Security 使用数据库认证
考虑状态值时,有的就设置相应值,没有的就设置为 TRUE
一篇博客帮你搞定 Spring Security 使用数据库认证
此时这个状态值就表示当前用户是否可用。

五、用户退出

可以访问路径logout.do,便会杀死 session,然后跳到设置的 login.jsp 界面
一篇博客帮你搞定 Spring Security 使用数据库认证
对应的网页设置,给注销绑定单击事件:
一篇博客帮你搞定 Spring Security 使用数据库认证
一篇博客帮你搞定 Spring Security 使用数据库认证

赞(0) 打赏
未经允许不得转载:Java小咖秀 » 一篇博客帮你搞定 Spring Security 使用数据库认证
免责声明

抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

专注Java技术 100年

联系我们联系我们

你默默的关注就是最好的打赏~

支付宝扫一扫打赏

微信扫一扫打赏