spring security elementui前后端分离登陆
时间: 2023-06-28 15:06:02 浏览: 142
Spring Security和ElementUI可以很好地配合使用,实现前后端分离登录。
首先,你需要在Spring Boot中集成Spring Security。可以通过引入spring-boot-starter-security依赖来实现。在配置类中,你需要实现WebSecurityConfigurerAdapter,重写configure()方法,配置Spring Security的相关参数和行为。例如:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/auth/**")
.permitAll()
.anyRequest()
.authenticated();
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
```
在上述代码中,我们配置了自定义的用户认证服务(CustomUserDetailsService),密码加密方式(BCryptPasswordEncoder),JWT认证过滤器(JwtAuthenticationFilter),以及请求权限控制规则。
接下来,我们需要实现登录接口和JWT认证过滤器。具体实现可以参考下面代码:
```java
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenProvider tokenProvider;
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsernameOrEmail(),
loginRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.generateToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
}
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenProvider tokenProvider;
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
String jwt = getJwtFromRequest(request);
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
Long userId = tokenProvider.getUserIdFromJWT(jwt);
UserDetails userDetails = customUserDetailsService.loadUserById(userId);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception ex) {
logger.error("Could not set user authentication in security context", ex);
}
filterChain.doFilter(request, response);
}
private String getJwtFromRequest(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
}
```
在上述代码中,我们实现了登录接口(AuthController),使用AuthenticationManager进行用户认证,使用JwtTokenProvider生成JWT token,并返回给客户端。
同时,我们实现了JWT认证过滤器(JwtAuthenticationFilter),在每个请求到达后端时,检查请求头中是否携带有效的JWT token,如果是,则将用户信息放入Spring Security上下文中,以便后续进行权限控制。
在ElementUI中,我们可以使用axios库发送登录请求,获取JWT token,并存储在localStorage中,以便后续请求时携带:
```javascript
// 登录
axios.post('/api/auth/login', {
usernameOrEmail: this.form.username,
password: this.form.password
}).then(response => {
const token = response.data.accessToken
localStorage.setItem('accessToken', token)
axios.defaults.headers.common.Authorization = `Bearer ${token}`
this.$router.push({ path: '/' })
}).catch(error => {
console.log(error)
})
```
在每个请求中,我们需要在请求头中添加Authorization字段,携带JWT token:
```javascript
// 示例:获取用户列表
axios.get('/api/users', {
headers: {
Authorization: `Bearer ${localStorage.getItem('accessToken')}`
}
}).then(response => {
console.log(response.data)
}).catch(error => {
console.log(error)
})
```
以上就是如何使用Spring Security和ElementUI实现前后端分离登录的基本步骤。当然,具体实现还需要考虑更多细节和安全性问题。
阅读全文