一、引入依赖(基于secruity)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
二、相关文件配置
2.1 系统提供默认用户user 并随机生成一组加密密码
2.2、properties或yaml中
#默认账号密码和用户角色
#spring.security.user.name=yxj
#spring.security.user.password=1234
#spring.security.user.roles=admin
2.3、自定义配置文件(重写类 WebSecurityConfigurerAdapter)
在config包下创建一个类为MyWebSecurityConfig继承于WebSecurityConfigurerAdapter,并重写其方法 configure
2.2.1、configure(AuthenticationManagerBuilder auth) (配置不同的认证方式,并指定用户的角色认定)
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
//在 configure(AuthenticationManagerBuilder auth) 方法中,你可以使用 auth 对象来配置不同类型的认证方式,例如内存认证、数据库认证、LDAP认证等。
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("admin").password("123456").roles("ADMIN","USER")
.and()
.withUser("chen").password(new BCryptPasswordEncoder().encode("123456")).roles("USER")// 使用BCryptPasswordEncoder进行加密
.and()
.withUser("yxj").password("123456").roles("ADMIN","DBA");
// 2、数据库认证
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username = ?")
.authoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username = ?")
.passwordEncoder(passwordEncoder());
// 3、LDAP认证
auth.ldapAuthentication()
.userDnPatterns("uid={0},ou=users")
.groupSearchBase("ou=groups")
.contextSource()
.url("ldap://localhost:389/dc=example,dc=com")
.and()
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute("userPassword");
// 4、自定义用户认证
configure(AuthenticationManagerBuilder auth)
}
}
2.2.2、 configure(HttpSecurity http)
(1、设置不同身份的人可以访问页面的权限
2、认证成功或失败所执行的逻辑
3、注销时和注销成功后所执行的逻辑)
package com.xmut.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.*;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
@Configuration
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
//在 configure(AuthenticationManagerBuilder auth) 方法中,你可以使用 auth 对象来配置不同类型的认证方式,例如内存认证、数据库认证、LDAP认证等。
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//1、内存认证
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("admin").password("123456").roles("ADMIN","USER")
.and()
.withUser("chen").password(new BCryptPasswordEncoder().encode("123456")).roles("USER")//面没使用BCryptPasswordEncoder进行加密
.and()
.withUser("yxj").password("123456").roles("ADMIN","DBA");
// //2、数据库认证
// auth.jdbcAuthentication()
// .dataSource(dataSource)
// .usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username = ?")
// .authoritiesByUsernameQuery("SELECT username, authority FROM authorities WHERE username = ?")
// .passwordEncoder(passwordEncoder());
//3、LDAP认证
//auth.ldapAuthentication()
//.userDnPatterns("uid={0},ou=users")
//.groupSearchBase("ou=groups")
//.contextSource()
//.url("ldap://localhost:389/dc=example,dc=com")
//.and()
//.passwordCompare()
//.passwordEncoder(new BCryptPasswordEncoder())
//.passwordAttribute("userPassword");
//4、自定义用户认证
//configure(AuthenticationManagerBuilder auth)
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//定义访问权限规则
http.authorizeRequests()
.antMatchers("/admin/**")//指定路径"/admin/**"需要具备"ADMIN"角色才能访问。
.hasRole("ADMIN")
.antMatchers("/user/**")
.access("hasAnyRole('ADMIN','USER')")
.antMatchers("db/**")
.access("hasRole('admin') and hasRole('DBA')")
.anyRequest() //其他所有路径需要进行认证才能访问。
.authenticated()
.and()
.formLogin()//配置登录表单和登录处理URL为"/login",并允许所有用户访问该登录页面。
// .loginPage("/login_page") //自定义登录页面未指定,将生成默认页面
.loginProcessingUrl("/login")
.usernameParameter("name")
.passwordParameter("passwd")
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
//认证成功后执行的自定义逻辑
System.out.println("用户认证成功");
httpServletResponse.sendRedirect("/user/hello");
//重定向到指定页面
//也可以在响应中返回一些消息
// httpServletResponse.getWriter().write("登录成功");
}
})
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
//认证失败后执行的自定义逻辑
System.out.println("用户认证失败");
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter out = httpServletResponse.getWriter();
httpServletResponse.setStatus(401);
HashMap<String, Object> map = new HashMap<>();
map.put("status",401);
if(e instanceof LockedException){
map.put("msg","账户被锁定,登录失败");
}else if(e instanceof BadCredentialsException){
map.put("msg","账户或密码输入错误,登录失败");
}else if (e instanceof DisabledException){
map.put("msg","账户被禁用,登录失败");
}else if(e instanceof AccountExpiredException){
map.put("msg","账户过期,登录失败");
}else if(e instanceof CredentialsExpiredException){
map.put("msg","密码过期,登录失败");
}else {
map.put("msg","登录失败");
}
ObjectMapper om= new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();
}
})
.permitAll()
.and()
.logout().logoutUrl("/logout")//启用注销功能的同时指定注销url为/logout
.clearAuthentication(true) //注销时清除用户的认证信息
.addLogoutHandler(new LogoutHandler() {
@Override
public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) {
//注销时执行的自定义逻辑
}
})
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
//编写自定义逻辑来处理注销成功后的操作
}
})
// .csrf()//禁用跨站请求伪造(CSRF)保护
// .disable()
.and();
}
}
引用:springBoot整合springSecurity(认证)_springbootsecurity登录认证_qingqingyyds的博客-CSDN博客