我正在使用OAuth2开发示例Spring Boot应用程序.问题是在localhost:8080上托管的客户端调用https:// localhost:8443 / oauth / authorize来授权自己(隐式授权类型),但由于/ oauth / authorize要求用户进行身份验证,他们会被重定向到登录页面https:// localhost:8443 / login.
这是所有预期的,但是当用户登陆登录页面时,所有查询字符串(包括redirect_uri)都将丢失.用户登录并重定向到https:// localhost:8443,而不是指定的http:// localhost:8080的redirect_uri.
在使用服务器的登录表单登录后,是否有某种方法可以将用户重定向回客户端?我在配置中遗漏了什么吗?我可以根据需要发布更多内容.
授权请求如下所示:https:// localhost:8443 / oauth / authorize?response_type = token& state = 6c2bb162-0f26-4caa-abbe-b65f7e5c6a2e& redirect_uri = http:// localhost:8080& client_id = admin
SecurityConfig:
@Configuration
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final Logger log = LoggerFactory.getLogger(WebSecurityConfig.class);
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
@SuppressWarnings("deprecation")
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers()
.antMatchers("/**")
.and()
.addFilterAfter(new CsrfCookieGeneratorFilter(),CsrfFilter.class)
.exceptionHandling()
.accessDeniedPage("/login?authorization_error=true")
.and()
.authorizeRequests()
.antMatchers("/resources/**","/csrf").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("j_username")
.passwordParameter("j_password")
.defaultSuccessUrl("/",false)
.failureUrl("/login?authentication_error=true")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID","CSRF-TOKEN")
.permitAll()
.and()
.headers()
.frameOptions()
.disable();
}
的OAuthConfig:
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Inject
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Primary
@Bean
public ResourceServerTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(tokenStore());
return tokenServices;
}
@Bean
public ApprovalStore approvalStore() throws Exception {
TokenApprovalStore approvalStore = new TokenApprovalStore();
approvalStore.setTokenStore(tokenStore());
return approvalStore;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("read-only")
.secret("readme")
.resourceIds(RESOURCE_ID)
.authorizedGrantTypes("implicit","password","refresh_token")
.authorities(Constant.USER)
.scopes("read")
.autoApprove(true)
.redirectUris("https://localhost:8443")
.and()
.withClient("admin")
.secret("admin")
.resourceIds(RESOURCE_ID)
.authorizedGrantTypes("implicit","refresh_token")
.authorities(Constant.USER,Constant.ADMIN)
.scopes("read","write")
.autoApprove(true)
.redirectUris("https://localhost:8443","http://localhost:8080")
.and()
.withClient("super-admin")
.secret("super")
.resourceIds(RESOURCE_ID)
.authorizedGrantTypes("implicit","write","delete")
.redirectUris("https://localhost:8443");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer configurer) throws Exception {
configurer
.tokenStore(tokenStore())
.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security)
throws Exception {
security.realm("hubble/client");
}
}
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId(RESOURCE_ID);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers()
.antMatchers("/api/**")
.and()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS,"/api/**").permitAll()
.antMatchers(HttpMethod.GET,"/api/**").access("#oauth2.hasScope('read')")
.antMatchers(HttpMethod.POST,"/api/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.PATCH,"/api/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.PUT,"/api/**").access("#oauth2.hasScope('write')")
.antMatchers(HttpMethod.DELETE,"/api/**").access("#oauth2.hasScope('delete')")
.antMatchers("/api/**").access("hasRole('" + Constant.USER + "')")
.and()
.anonymous().authorities(Constant.ANONYMOUS)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,proxyTargetClass = true)
protected static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
OAuth2MethodSecurityExpressionHandler methodHandler = new OAuth2MethodSecurityExpressionHandler();
return methodHandler;
}
}
最佳答案
只有表单身份验证才会出现此问题,并且该问题与OAuth无关.
org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint有一个
buildRedirectUrlToLoginPage方法,用于创建登录URL并忘记查询字符串.
原文链接:https://www.f2er.com/spring/432211.htmlorg.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint有一个
buildRedirectUrlToLoginPage方法,用于创建登录URL并忘记查询字符串.
>而不是将用户重定向到授权网址,我们直接重定向到登录页面.
>登录页面有一个控制器,用于检查用户是否已登录,如果是,则重定向到授权URL,如果存在redirect_uri或默认应用程序URL为redirect_uri.
>从这里,redirect_uri由授权网址正确处理.
步骤2中的示例LoginController可能如下所示:
@Controller
@RequestMapping(value = {"/login"})
public class LoginController {
@RequestMapping(method = RequestMethod.GET)
public String getPage(HttpServletRequest request,HttpServletResponse response,Principal principal)
throws IOException {
if (principal != null) { //depends on your security config,maybe you want to check the security context instead if you allow anonym access
String redirect_uri = request.getParameter("redirect_uri");
//here you must get all the other attributes thats needed for the authorize url
if (redirect_uri == null) {
redirect_uri = "https://your.default.app.url";
}
return "redirect:https://localhost:8443/oauth/authorize?response_type=token&state=6c2bb162-0f26-4caa-abbe-b65f7e5c6a2e&client_id=admin&redirect_uri=" + URLEncoder.encode(redirect_uri,"UTF-8");
}
return "login";
}
}