Java SpringSecurityOAuth2:如何为两种类型的用户提供两个独立的登录链接?
我正在创建一个web应用程序,它有两种类型的用户,比如a和B。目前,登录流是这样的Java SpringSecurityOAuth2:如何为两种类型的用户提供两个独立的登录链接?,java,spring-boot,login,oauth-2.0,Java,Spring Boot,Login,Oauth 2.0,我正在创建一个web应用程序,它有两种类型的用户,比如a和B。目前,登录流是这样的 @EnableOAuth2Sso @Configuration public class WebSecurityConfigurator extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http
@EnableOAuth2Sso
@Configuration
public class WebSecurityConfigurator extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/index.html")
.permitAll()
.anyRequest()
.authenticated();
}
}
index.html
上有一个登录链接,指向/login
index.html
@EnableOAuth2Sso
@Configuration
public class WebSecurityConfigurator extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/index.html")
.permitAll()
.anyRequest()
.authenticated();
}
}
我想简化这个过程,其中
/login-A
和/login-B
基本上这是可能的,但与单个
@enableAuth2sso
注释相比,需要更多的配置工作。使用此注释时,它将应用SSOSecurityConfigure
,该配置程序将专用的OAuth2ClientAuthenticationProcessingFilter
注册为给定模式(/**
在您的情况下)的登录页面路径,该路径来自OAuth2ssProperties
(/login
)。但是,在同一应用程序中必须有多个@enableAuth2sso
和OAuth2ssoProperty
类。因此,您需要手动注册多个websecurityConfigureAdapter
,并为每种类型的用户注册相应的OAuth2ClientAuthenticationProcessingFilter
,使用不同的登录页面/模式/授权逻辑。1-配置Spring安全配置文件2-编写自定义身份验证成功处理程序类
<user name="userA" password="userApass" authorities="ROLE_A" />
<user name="userB" password="userBpass" authorities="ROLE_B" />
protected String determineTargetUrl(Authentication authentication) {
boolean isUserA = false;
boolean isUserB= false;
Collection<? extends GrantedAuthority> authorities
= authentication.getAuthorities();
for (GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals("ROLE_A")) {
isUserA = true;
break;
} else if (grantedAuthority.getAuthority().equals("ROLE_B")) {
isUserB = true;
break;
}
}
if (isUserA) {
return "/pageA.html";
} else if (isUserB) {
return "/pageB.html";
} else {
throw new IllegalStateException();
}
}
受保护的字符串determinateTargetURL(身份验证){
布尔值isUserA=false;
布尔值isUserB=false;
集合如果使用@enableouth2client
代替@enableouth2sso
,则可以定义多个OAuth2ClientAuthenticationProcessingFilter
您的配置类似于
@EnableOAuth2Client
@RestController
@Configuration
public class WebSecurityConfigurator extends WebSecurityConfigurerAdapter {
@Autowired
OAuth2ClientContext oauth2ClientContext;
@RequestMapping("/user")
public Principal user(Principal principal) {
return principal;
}
// @formatter:off
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/", "/login**", "/webjars/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.logout()
.logoutSuccessUrl("/").permitAll().and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
// @formatter:on
private Filter ssoFilter() {
CompositeFilter filter = new CompositeFilter();
List filters = new ArrayList<>();
OAuth2ClientAuthenticationProcessingFilter googleFilterA = new OAuth2ClientAuthenticationProcessingFilter(
"/login/googleA");
OAuth2RestTemplate googleTemplateA = new OAuth2RestTemplate(googleA(), oauth2ClientContext);
googleFilterA.setRestTemplate(googleTemplateA);
tokenServices = new UserInfoTokenServices(googleResource().getUserInfoUri(), googleA().getClientId());
tokenServices.setRestTemplate(googleTemplateA);
googleFilterA.setTokenServices(tokenServices);
OAuth2ClientAuthenticationProcessingFilter googleFilterB = new OAuth2ClientAuthenticationProcessingFilter(
"/login/googleB");
OAuth2RestTemplate googleTemplateB = new OAuth2RestTemplate(googleB(), oauth2ClientContext);
googleFilterB.setRestTemplate(googleTemplateB);
tokenServices = new UserInfoTokenServices(googleResource().getUserInfoUri(), googleB().getClientId());
tokenServices.setRestTemplate(googleTemplateB);
googleFilterB.setTokenServices(tokenServices);
filters.add(googleFilterA);
filters.add(googleFilterB);
filter.setFilters(filters);
return filter;
}
@Bean
public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
@Bean
@ConfigurationProperties("google.clientA")
public AuthorizationCodeResourceDetails googleA() {
return new AuthorizationCodeResourceDetails();
}
@Bean
@ConfigurationProperties("google.resource")
public ResourceServerProperties googleResource() {
return new ResourceServerProperties();
}
@Bean
@ConfigurationProperties("google.clientB")
public AuthorizationCodeResourceDetails googleB() {
return new AuthorizationCodeResourceDetails();
}
}
对于这两种类型的用户,index.html将有两个链接/login/googleA
和/login/googleB
有关更多详细信息,请参阅以下教程
更新-
要重定向到不同的页面,您可以为以下两个客户端扩展OAuth2ClientAuthenticationProcessingFilter
类:
class GoogleAAuthenticationProcessingFilter extends OAuth2ClientAuthenticationProcessingFilter {
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain chain, Authentication authResult) throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
// here you can redirect to whatever location you want to
}
}
class GoogleBAuthenticationProcessingFilter extends OAuth2ClientAuthenticationProcessingFilter {
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain chain, Authentication authResult) throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
// here you can redirect to whatever location you want to
}
}
并使用扩展类
OAuth2ClientAuthenticationProcessingFilter googleFilterA = new GoogleAAuthenticationProcessingFilter(
"/login/googleA");
OAuth2ClientAuthenticationProcessingFilter googleFilterB = new GoogleBAuthenticationProcessingFilter(
"/login/googleB");
在登录之前,您如何知道用户类型(A或B)?您不需要他们先登录吗?您当前的流程很有意义。另外,您的流程如何简化为两个链接而不是一个链接?@KeatsPeeks让我们假设我有猫和狗作为用户,所以猫会单击“以猫的身份登录”,狗会单击“以狗的身份登录”。这样,它将隐含用户类型。这样,我不需要在登录后询问用户。只需少一步,前端的逻辑也少一点。您可以尝试使用较低级别的注释“@EnableOAuth2Client”代替“@EnableOAuth2SO”。但它需要更多的代码。请参阅本教程-我已经更新了我的答案le重定向到不同的页面。除了重定向部分外,它是有效的。这两个链接始终重定向到homepage(/)@Registered User-我已更新我的答案以处理重定向到不同页面的问题。