编辑:
org.springframework.security日志:
2022-01-17 12:31:03.495 IST
2022-01-17 10:31:03.495 DEBUG [080-exec-5] o.s.s.w.s.SessionManagementFilter - Request requested invalid session id D5F8BA31A3D7466AK3K3C8EA26A4F037
Default
2022-01-17 12:31:03.495 IST
2022-01-17 10:31:03.495 DEBUG [080-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
Debug
2022-01-17 12:31:03.495 IST
"Request requested invalid session id D5F8BA31A3D7466AK3K3C8EA26A4F037"
Debug
2022-01-17 12:31:03.495 IST
"Set SecurityContextHolder to anonymous SecurityContext"
Default
2022-01-17 12:31:03.494 IST
2022-01-17 10:31:03.494 DEBUG [080-exec-5] o.s.s.w.c.SecurityContextPersistenceFilter - Set SecurityContextHolder to empty SecurityContext
Debug
2022-01-17 12:31:03.494 IST
"Set SecurityContextHolder to empty SecurityContext"
Default
2022-01-17 12:31:03.493 IST
2022-01-17 10:31:03.493 DEBUG [080-exec-5] o.s.security.web.FilterChainProxy - Securing GET /logo192.png
Debug
2022-01-17 12:31:03.493 IST
"Securing GET /logo192.png"
***但是,如果我在获得有效身份验证后查看日志中的一些请求:
调试2022-01-17 12:31:03.945 IST“将SecurityContextHolder设置为SecurityContextImpl[Authentication=OAuth2AuthenticationToken[Principal=com..security.oauth.CustomOAuth2User@,凭据=[受保护],Authenticated=true,Details=WebAuthenticationDetails[RemoteIpAddress=***,SessionId=9438C880A19C93AADJI206B8B3386],授予的权限=[ROLE\u USER,SCOPE_https://www.googleapis.com/auth/userinfo.email,范围_https://www.googleapis.com/auth/userinfo.profile,SCOPE\u openid]]”调试
2022-01-17 12:31:03.945IST"检索到的SecurityContextImpl[Authentication=OAuth2AuthenticationToken[主体=com...security.oauth.CustomOAuth2User@,凭据=[PROTECTED], Authenticated=true,详细信息=WebAuthentication详细信息[远程地址=***, SessionId=9438C880A19C93AADJI206B9B8B3386],授予权限=[ROLE_USER,SCOPE_https://www.googleapis.com/auth/userinfo.email,SCOPE_https://www.googleapis.com/auth/userinfo.profile,SCOPE_openid]]"Debug
2022-01-17 12:31:03.945 IST“检索到的SecurityContextImpl[Authentication=OAuth2AuthenticationToken[Principal=com..security.oauth.CustomOAuth2User@,凭据=[PROTECTED],Authenticated=true,Details=WebAuthenticationDetails[RemoteIpAddress=***,SessionId=9438C880A19C93AADJI206B9B8B3386],授予的权限=[ROLE_USER,SCOPE_https://www.googleapis.com/auth/userinfo.email,范围_https://www.googleapis.com/auth/userinfo.profile,SCOPE\u openid]]”默认值
2022-01-17 12:31:03.944 IST 2022-01-17 10:31:03.944调试[080-exec-8]o.s.security。网状物FilterChainProxy-保护GET/auth/api/getBasicInfo
会话id似乎不一致
我使用Spring Security builtin oauth2社交登录选项,我使用onAuthentiation成功方法实现了一个OAuth2Login成功类,在其中我获取了与我从oauth获得的社交ID相对应的用户:
CustomOAuth2User oAuth2User = (CustomOAuth2User) authentication.getPrincipal();
int sociald = oAuth2User.getAttribute("id");
User user = usersUtils.getUserBySocailId(socialId);
enter code here
// add the user details to the Auth
SecurityContextHolder.clearContext();
((OAuth2AuthenticationToken) authentication).setDetails(user);
SecurityContextHolder.getContext().setAuthentication(authentication);
如果我在onAuthentication成功中进行调试,我可以看到包含所有用户详细信息的有效身份验证。
登录后,我重定向到主页,并向服务器发送身份验证获取请求以检查是否有用户登录。
问题是,50%的请求成功完成,用户可以进行身份验证请求。
但另外50%我自动重定向到登录页面,当我检查日志时,看到Spring boot说用户未经身份验证,身份验证丢失。
但是在onAuthenticationSuccess中,我总能看到正确的身份验证。
我的Application SecurityConfig看起来像这样:
http.csrf().disable().authorizeRequests()
.antMatchers("/login*", "/signin/**", "/signup/**", "/oauth2/**").permitAll()
.antMatchers(Constants.ADMIN_PREFIX + "/**").hasRole("ADMIN")
.antMatchers(Constants.AUTH_PREFIX + "/**").hasAnyRole("ADMIN", "USER")
.antMatchers(Constants.PUBLIC_PREFIX + "/**").permitAll()
.anyRequest().permitAll()
.and()
.exceptionHandling().authenticationEntryPoint(new UnauthenticatedRequestHandler())
.and()
.formLogin()
.passwordParameter("password")
.usernameParameter("email")
.loginPage("/Login")
.loginProcessingUrl("/loginSecure").permitAll().successHandler(new LoginSuccess()).failureHandler(new FailureSuccess())
.and()
.oauth2Login()
.loginPage("/Login")
.userInfoEndpoint()
.userService(oAuth2UserService)
.and()
.successHandler(new OAuth2LoginSuccess())
.and()
.rememberMe()
.rememberMeParameter("remember-me")
.tokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(21))
.userDetailsService(this.applicationUserService)
.and()
.logout()
.clearAuthentication(true).invalidateHttpSession(true).logoutSuccessUrl("/login")
.addLogoutHandler(new CustomLogOutHandler());
这是我检查用户是否登录的功能:
@GetMapping(Constants.AUTH_PREFIX + "/checkUserLogged")
public Integer checkUserLogged(Authentication authentication,HttpServletRequest request) {
try{
if (authentication != null) {
User (User) authentication.getDetails();
if (user == null) {
return -1;
}
return user.getId();
}
}
catch (Exception e){
logger.warning(e.getLocalizedMessage());
}
return -1;
}
但当问题发生时,它无法运行控制器,因为spring security以前返回了未授权的错误。
提前谢谢你的帮助
我找到了解决方案,我希望这能有所帮助。
给我带来问题的是GCP和GAE使用服务器的多个实例,如果用户登录了某个实例并不意味着其他实例也熟悉它,因为Spring HTTPS在内存中。
我在应用程序中使用以下配置,将会话平台切换为使用spring会话jdbc。属性:
spring.session.store-type=jdbc
--您可以使用redis而不是jdbc,只要会话存储在所有实例之间的共享位置。
还将事务管理器添加到安全配置:
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
并添加了以下配置:
http.csrf().disable()
.sessionManagement()
.maximumSessions(1)
.and()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
此外,如@stringy05所述,authrizenClient存储库也需要更新:
/**
* Use the servlet container session store for authorized OAuth2 Clients
*/
@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository() {
return new HttpSessionOAuth2AuthorizedClientRepository();
}
并添加。httpconfig的授权客户端存储行:
....
.oauth2Login()
.loginPage("/Login")
.authorizedClientRepository(authorizedClientRepository)
.authorizationEndpoint().and()
.userInfoEndpoint()
.userService(oAuth2UserService)
.and()
.successHandler(new OAuth2LoginSuccess())
....
关于GAE,我在应用程序中添加了以下内容。yaml文件:
network:
session_affinity: true
这不是一个答案,但评论太长。。
看起来这节课因为某种原因而迷失了方向,一定要关注这一点。
在默认的Spring Boot配置中,会话由底层servlet容器管理,因此值得检查其是否正常工作。检查事项:
基本上启用所有html" target="_blank">日志,并在出现问题时尝试从servlet容器中观察会话状态。
让oauth2会话正常工作并非易事,尤其是考虑到没有多少好的博客/文档描述spring boot正在做什么。
这就是说,下面是一个使用OAuth 2登录的、支持Redis的Spring Boot配置的示例,它可能对您很有用,可以作为参考:
应用配置:
spring:
session:
store-type: redis
redis:
namespace: sample:api
flush-mode: immediate
redis:
host: localhost
port: 6379
security:
oauth2:
client:
registration:
# add your oauth2 client details here
public class SecurityConfig<S extends Session> extends WebSecurityConfigurerAdapter {
private final ClientRegistrationRepository clientRegistrationRepository;
@Autowired
private RedisIndexedSessionRepository redisIndexedSessionRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors(Customizer.withDefaults())
.sessionManagement()
.maximumSessions(1)
.sessionRegistry(sessionRegistry())
.and()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.authorizeRequests(
a -> a.antMatchers("/api/login/callback").permitAll().anyRequest().authenticated())
.oauth2Login()
.authorizationEndpoint()
.authorizationRequestResolver(
new DefaultOauth2AuthorizationRequestResolver(
this.clientRegistrationRepository, OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI))
.and()
.defaultSuccessUrl("http://localhost:3000/users")
.authorizedClientRepository(authorizedClientRepository());
}
@Bean
public SpringSessionBackedSessionRegistry<?> sessionRegistry() {
return new SpringSessionBackedSessionRegistry<>(this.redisIndexedSessionRepository);
}
/**
* Use the servlet container session store for authorized OAuth2 Clients
*/
@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository() {
return new HttpSessionOAuth2AuthorizedClientRepository();
}
/**
* specify CORS to work from SPA UI
*/
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOriginPatterns(List.of("http://localhost:3000*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Configuration
public static class HttpSessionEventPublisherConfig {
/**
* enables session expiry notification
*
* <p>Needs to be declared in a different class from the `SpringSessionBackedSessionRegistry` to
* avoid a circular dependency
*/
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
}
我正在尝试使用OAuth2实现开发一个带有Spring Security性的rest api。但是如何删除基本身份验证呢。我只想向body发送用户名和密码,并在postman上获取令牌。 要删除基本身份验证,并从邮递员的get token中发送body标记中的用户名密码吗 我遇到了一些问题{"错误":"未经授权","error_description":"没有客户端身份验证。尝试添加适当的身份验证
但是这个配置的问题是我只能以用户Euclid的身份登录。但我想作为每一个可用的用户登录。 但是对于另一个配置,我会在日志中得到这样的消息,即找到了该用户,但已经发生了驱逐。 2017-04-20 09:36:16]ldap_driver.debug:ldap_search(dc=example,dc=com,(&(&(objectclass=person))(UID=einstein)),[arr
我一直在尝试用Zuul、Eureka和Spring boot构建一个应用程序,最近我决定尝试登录。作为提醒,我已经配置了身份验证服务(使用OAuth2.0),并且可以使用curl成功地进行身份验证。我还可以向其他拥有受保护资源的微服务发出get请求(同样,只能使用CURL,因为我可以在身份验证头中注入令牌)。我关心的是,我想以Zuul为门户来做这件事。[![在此处输入图像说明][1]][1] 当我
让OAUTH2和管理endpoint工作的正确方法是什么?
我试图得到一个API查询到python。命令行 给出一些json输出。myToken是一个十六进制变量,始终保持不变。我想从python中调用它,这样我就可以循环使用不同的ID并分析输出。有什么想法吗?在需要身份验证之前,我已经使用urllib2完成了这项工作。我还查看了requests模块,但不知道如何实现。 非常感谢。