Spring boot 我可以使用两个不同的表来登录SpringSecurity的SpringBoot应用程序吗?
在我当前的项目中,我有两个独立的实体Spring boot 我可以使用两个不同的表来登录SpringSecurity的SpringBoot应用程序吗?,spring-boot,authentication,spring-security,Spring Boot,Authentication,Spring Security,在我当前的项目中,我有两个独立的实体 用户:-对用户进行身份验证 客户:-验证客户身份 我很困惑,SpringSecurity如何管理同一项目中两个独立实体的登录过程 到目前为止,它与一个用户实体一起工作,现在我必须在Customer表的帮助下为客户集成一个登录 可能吗 注:-由于其他一些要求,我不能对用户和客户使用相同的表。 我正在分享一些代码以获得更多许可 下面的代码是用户详细信息服务的实现。 } 登录api @PostMapping(“/userLogin”) @定时 公众反应授权( @有
@PostMapping(“/userLogin”)
@定时
公众反应授权(
@有效@RequestBody UserLoginReq UserLoginReq){
Map responseData=null;
试一试{
UsernamePasswordAuthenticationToken authenticationToken=新UsernamePasswordAuthenticationToken(
userLoginReq.getUsername(),userLoginReq.getPassword());
身份验证=this.authenticationManager
.验证(authenticationToken);
SecurityContextHolder.getContext()
.setAuthentication(认证);
}首先,客户也是用户,不是吗?所以可能更简单的解决方案是将客户也创建为用户(使用一些标志/db字段
usertype={user | customer |……}
)。如果您仍然需要管理两个实体,您的方法是正确的,但在您的DetailService中,只需实现另一个方法,该方法将读取customer实体,然后创建spring的用户。是的,您可以将用户类型组合在用户名中,并用如下字符分隔:
例如:
String userName=inputUserName+“:APP\u USER”;
UsernamePasswordAuthenticationToken authenticationToken=
新用户名PasswordAuthenticationToken(用户名、密码);
在UserDetailsService.loadUserByUsername(用户名)
首先,获取userName
部分,同时获取userType
部分。
现在在userType
base上,您可以决定应该从哪个表中验证用户
String userNamePart = null;
if (userName.contains(":")) {
int colonIndex = userName.lastIndexOf(":");
userNamePart = userName.substring(0, colonIndex);
}
userNamePart = userNamePart == null ? userName : userNamePart;
String userTypePart = null;
if (userName.contains(":")) {
int colonIndex = userName.lastIndexOf(":");
userTypePart = userName.substring(colonIndex + 1, userName.length());
}
“UserDetailsService”接口中只有一个方法,我已经实现了。请您再解释一下,我如何实现另一个方法?以及这个新方法将如何得到调用,到目前为止,它自动调用默认方法“loadUserByUsername”。如果您可以提供一些与此相关的链接,那就太好了……在这种方法中,您可以通过调用或另一个存储库来区分用户和客户。如果userRepository不返回用户,请尝试调用customerRepository。但我仍然认为您应该修改应用程序逻辑,并且只为auth用户使用一个实体。但是在这种情况下ase如果我想从customer表中验证凭据,并且相同的凭据存在于user表中而不是customer表中,那么它也将有效。对于多个身份验证过程来说,这是一种糟糕的方法吗?
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final UserDetailsService userDetailsService;
private final TokenProvider tokenProvider;
private final CorsFilter corsFilter;
private final SecurityProblemSupport problemSupport;
public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService,TokenProvider tokenProvider,CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
this.authenticationManagerBuilder = authenticationManagerBuilder;
this.userDetailsService = userDetailsService;
this.tokenProvider = tokenProvider;
this.corsFilter = corsFilter;
this.problemSupport = problemSupport;
}
@PostConstruct
public void init() {
try {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/swagger-ui/index.html");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.csrf()
.disable()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/userLogin").permitAll()
.antMatchers("/api/account/reset-password/init").permitAll()
.antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/info").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/v2/api-docs/**").permitAll()
.antMatchers("/swagger-resources/configuration/ui").permitAll()
.antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN)
.and()
.apply(securityConfigurerAdapter());
}
private JWTConfigurer securityConfigurerAdapter() {
return new JWTConfigurer(tokenProvider);
}
@PostMapping("/userLogin")
@Timed
public Response<JWTToken> authorize(
@Valid @RequestBody UserLoginReq userLoginReq) {
Map<String, Object> responseData = null;
try {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
userLoginReq.getUsername(), userLoginReq.getPassword());
Authentication authentication = this.authenticationManager
.authenticate(authenticationToken);
SecurityContextHolder.getContext()
.setAuthentication(authentication);
String userNamePart = null;
if (userName.contains(":")) {
int colonIndex = userName.lastIndexOf(":");
userNamePart = userName.substring(0, colonIndex);
}
userNamePart = userNamePart == null ? userName : userNamePart;
String userTypePart = null;
if (userName.contains(":")) {
int colonIndex = userName.lastIndexOf(":");
userTypePart = userName.substring(colonIndex + 1, userName.length());
}