SpringBoot+SpringSecurity基本使用
1. 引入Spring Security
在pom.xml中添加Spring Security的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2. 编写SecurityConfig
创建一个继承自WebSecurityConfigurerAdapter
的配置类,用于配置Spring Security相关内容。代码如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
在上面的代码中,我们首先通过@EnableWebSecurity
注解开启Web Security。然后,我们使用@Autowired
注解将UserDetailsService
注入到配置类中,UserDetailsService
用于根据用户名获取用户信息。在configure
方法中,我们将UserDetailsService
传递给AuthenticationManagerBuilder
,并使用passwordEncoder
方法返回的PasswordEncoder
对象对密码进行加密。PasswordEncoder
用于加密用户密码。
3. 编写登录页
创建一个Controller,并在其中定义返回登录页面的方法。代码如下:
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login";
}
}
在上述示例中,我们使用了@GetMapping
注解定义了一个GET请求。
4. 配置登录认证
我们需要创建一个实现UserDetailsService
接口的类,并定义用于获取用户信息的方法。代码如下:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用户不存在");
}
return user;
}
}
在上面的代码中,我们通过@Service
注解将UserDetailsServiceImpl
注入到Spring容器中。然后,我们实现loadUserByUsername
方法,该方法用于根据用户名查询用户信息。
5. 配置访问控制
我们可以通过方法authorizeRequests
配置访问权限。代码如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login", "/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").defaultSuccessUrl("/").permitAll()
.and()
.logout().permitAll();
}
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
在上述示例中,我们定义了两个不需要授权即可访问的URL:/login
和/register
。对于其他任何URL,用户必须先进行验证才能访问。在formLogin
配置中,我们使用了loginPage
方法指定了自定义的登录页面,通过defaultSuccessUrl
方法配置默认成功跳转的URL。在logout
配置中,我们允许用户进行注销操作。
SpringSecurity个性化登录配置详解
1. 美化登录页面
可以通过在resources/static下放置login.html文件,然后在SecurityConfig配置中配置loginPage方法指向该页面,从而实现美化登录页面的目的。
2. 自定义验证身份逻辑
我们可以通过传入一个AuthenticationProvider
对象,使用自定义校验逻辑,该类需要实现AuthenticationProvider
接口。示例代码如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new AuthenticationProvider() {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
if ("admin".equals(username) && "123456".equals(password)) {
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), grantedAuthorities);
} else {
throw new BadCredentialsException("用户名或密码错误");
}
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
});
}
}
在上面的代码中,我们自定义了一个AuthenticationProvider
对象,该对象实现了authenticate
方法,该方法用于验证用户身份是否正确。如果用户名和密码正确,我们返回一个UsernamePasswordAuthenticationToken
对象,该对象保存了用户的认证信息。否则,我们抛出一个BadCredentialsException
异常,该异常用于表示认证失败的情况。
3. 多方式登录
我们可以通过配置多个AuthenticationProvider
对象,实现多种登录方式。示例代码如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService());
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
auth.authenticationProvider(daoAuthenticationProvider);
InMemoryAuthenticationProvider inMemoryAuthenticationProvider = new InMemoryAuthenticationProvider();
inMemoryAuthenticationProvider.setUserDetailsService(userDetailsService());
inMemoryAuthenticationProvider.setPasswordEncoder(passwordEncoder());
auth.authenticationProvider(inMemoryAuthenticationProvider);
}
}
在上述示例中,我们配置了一个DaoAuthenticationProvider
(数据库验证)和一个InMemoryAuthenticationProvider
(内存验证)。如果第一个AuthenticationProvider
对象无法验证通过,Spring Security会尝试通过第二个AuthenticationProvider
验证。
4. 自定义登录成功后跳转的页面
我们可以使用defaultSuccessURL
方法指定成功之后的跳转页面。示例代码如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.loginPage("/login").permitAll()
.defaultSuccessUrl("/")
.and()
.logout().permitAll();
}
}
在上述示例中,我们使用了defaultSuccessURL
方法指定成功之后的跳转页面为根目录/
。当登录成功之后,用户将会被跳转到根目录页面。
5. 登录成功之后返回JSON
我们可以将登录成功之后返回JSON数据,示例代码如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.successHandler((request, response, authentication) -> {
response.setContentType("application/json;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"status\":\"success\", \"msg\":\"登录成功\"}");
out.flush();
out.close();
})
.failureHandler((request, response, exception) -> {
response.setContentType("application/json;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("{\"status\":\"error\", \"msg\":\"登录失败\"}");
out.flush();
out.close();
});
}
}
在上述示例中,我们将JSON数据写入到HttpServletResponse
中,并通过setContentType
方法设置了返回数据的类型为json。在登录失败的情况下,我们也执行了类似的操作。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot + Spring Security 基本使用及个性化登录配置详解 - Python技术站