如何为 RestController 配置 SpringBoot 认证
Posted
技术标签:
【中文标题】如何为 RestController 配置 SpringBoot 认证【英文标题】:How to configure SpringBoot authentication for RestController 【发布时间】:2021-12-09 08:33:23 【问题描述】:我有一个用户控制器包含
@PostMapping("/user/register")
public String register ( @RequestParam String name
, @RequestParam String password
, @RequestParam String email
, HttpServletRequest request)
@GetMapping("/user/confirm/token")
public Optional<User> confirm(@PathVariable(value = "token") String token)
和
@PostMapping("/user/login")
public ResponseEntity<String> login
( @RequestParam String email
, @RequestParam String password
, HttpServletRequest request
)
//System.out.println("post:/user/login email="+email);
User user = userService.login(email, password);
if (user==null)
return ResponseEntity.notFound().build();
HttpSession session = request.getSession(true); // createSession=true
session.setAttribute(SESSION_USER, user);
**cfgSecurity.setAthenticated(session, user);**
return ResponseEntity.ok("OK");
用户的角色是一个枚举。 问题是如何配置安全性。 这是我的配置类:
@Configuration
@EnableWebSecurity
public class CfgSecurity extends WebSecurityConfigurerAdapter
private static final String PRINCIPAL = "admin";
private static final String CREDENTIAL = "password";
@Autowired AuthenticationManager authenticationManager;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception // authentication
auth
.inMemoryAuthentication()
.withUser(PRINCIPAL).password(passwordEncoder().encode(CREDENTIAL))
.roles(roles());
@Override
protected void configure(HttpSecurity http) throws Exception // resource security
http.cors().and().csrf().disable()
.httpBasic()
/*
.and().authorizeRequests()
.antMatchers("/user/register").permitAll()//.hasRole("ADMIN")
.antMatchers("/user/confirm/**").permitAll()
.anyRequest().permitAll()
//.and().formLogin().loginPage("/user/login").permitAll()
*/
;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
//https://www.programcreek.com/java-api-examples/docs/?api=org.springframework.security.authentication.AuthenticationManager
return super.authenticationManagerBean();
@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder();
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
private static String[] roles()
String[] array = new String[Role.values().length];
for (Role role : Role.values())
array[role.ordinal()] = role.name();
return array;
public void setAthenticated(HttpSession session, User user)
//https://***.com/questions/4664893/how-to-manually-set-an-authenticated-user-in-spring-security-springmvc
try
Authentication authRequest = new UsernamePasswordAuthenticationToken
(PRINCIPAL, passwordEncoder().encode(CREDENTIAL)
, user.getAuthorities()
);
Authentication authentication = authenticationManager.authenticate(authRequest);
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
catch(Exception ex)
System.err.println(ex.toString());
它不起作用:我明白了 org.springframework.security.authentication.BadCredentialsException:错误的凭据。
这里是 User.getAuthorities(在 setAuthenticated 中引用):
@覆盖 公共收藏 getAuthorities()
final SimpleGrantedAuthority simpleGrantedAuthority =
new SimpleGrantedAuthority(role.toString());
return Collections.singletonList(simpleGrantedAuthority);
【问题讨论】:
【参考方案1】:这是它的工作方式:使用 AuthenticationManagerBuilder 的加密密码,但将其未加密传递给 UsernamePasswordAuthenticationToken。
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
auth.inMemoryAuthentication()
.withUser(PRINCIPAL).password(passwordEncoder().encode(CREDENTIAL))
.roles(roles());
public void setAthenticated(HttpSession session, User user)
Authentication authRequest = new UsernamePasswordAuthenticationToken
(PRINCIPAL, CREDENTIAL, user.getAuthorities());
Authentication authentication = authenticationManager
.authenticate(authRequest);
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
【讨论】:
以上是关于如何为 RestController 配置 SpringBoot 认证的主要内容,如果未能解决你的问题,请参考以下文章
WCF - 如何为 NTLM 身份验证配置 netTcpBinding?