我正在尝试使用与 Spring Security 集成的 ForgeRock OpenAM 设置 OAuth2-OpenID Connect,但收到以下错误
2019-06-17 15:01:42.576 DEBUG 62255 --- [nio-8090-exec-2] .o.s.r.w.BearerTokenAuthenticationFilter :
Authentication request for failed: org.springframework.security.oauth2.core.OAuth2AuthenticationException:
An error occurred while attempting to decode the Jwt:
Signed JWT rejected: Another algorithm expected, or no matching key(s) found
Run Code Online (Sandbox Code Playgroud)
Jwk .wellknown uri 返回以下支持的算法:
"id_token_signing_alg_values_supported": [
"PS384",
"ES384",
"RS384",
"HS256",
"HS512",
"ES256",
"RS256",
"HS384",
"ES512",
"PS256",
"PS512",
"RS512"
]
Run Code Online (Sandbox Code Playgroud)
解码后的 JWT 显示以下标头:
{
"typ": "JWT",
"zip": "NONE",
"alg": "HS256"
}
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以根据来自标头的值设置特定的 JwtDecoder 或强制 AM 使用一种特定算法?
我正在对Spring OAuth进行深入研究,我发现了一些相互矛盾的信息.有人可以澄清一下吗?
具体来说,本教程指出/oauth/token端点在向客户端应用程序授予刷新令牌之前处理用户名和密码.相比之下,春OAuth的开发手册中提到的/oauth/authorize和/oauth/token终点,但仍没有得到具体的关于他们如何工作.
是否/oauth/authorize做了100%的username/password/nOtherFactors检查,然后将信号/oauth/token端点发送一个刷新令牌给客户,让客户端将发送更新凭证到/oauth/token终点?
或者全部是由/oauth/token端点处理的?
之间的关系是/oauth/authorize和/oauth/token不同的对不同类型的补助?怎么样?
我有2个单独的Spring Boot应用程序,一个用作OAuth 2授权服务器,另一个用作资源服务器.我RemoteTokenServices在资源服务器中使用Spring 来检查授权服务器中的令牌.现在,我正在尝试在资源服务器应用程序中定义受保护的控制器代码,但我不确定如何将UserDetails类映射到通过OAuth 2机制提供的身份验证主体.
我已经使用自定义设置了我的授权服务器,该自定义TokenEnhancer向令牌添加了更多详细信息,以便/oauth/check_token?token=<token>返回自定义字段,我想将其映射到资源服务器控制器.
在更加单一的设置中,授权服务器也是资源服务器,我可以定义以这种方式使用经过身份验证的主体的控制器方法:
//User implements UserDetails
public Map<String, Object> getResource(@AuthenticationPrincipal User user) {
//code that uses the user object
}
Run Code Online (Sandbox Code Playgroud)
但是,在更加分散的方法中,这似乎并不直接.映射失败,user参数最终成为空对象.我尝试使用以下方法:
public Map<String, Object> getResource(Authentication authentication) {
//code that uses the authentication object
}
Run Code Online (Sandbox Code Playgroud)
虽然上面的代码成功映射了身份验证详细信息,但它没有为我提供直接访问我通过TokenEnhancer前面提到的设置的自定义字段的方法.我似乎无法从Spring文档中找到任何关于此的内容.
我正在尝试将Spring boot 1.5应用程序移植到Spring Boot 2
现在我无法获得OAuth2访问令牌.
这是我成功使用Spring Boot 1.5的代码:
public static String loginAndGetAccessToken(String username, String password, int port) {
ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();
resourceDetails.setUsername(username);
resourceDetails.setPassword(password);
resourceDetails.setAccessTokenUri(String.format("http://localhost:%d/api/oauth/token", port));
resourceDetails.setClientId("clientapp");
resourceDetails.setClientSecret("123456");
resourceDetails.setGrantType("password");
resourceDetails.setScope(Arrays.asList("read", "write"));
DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, clientContext);
restTemplate.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter()));
return restTemplate.getAccessToken().toString();
}
Run Code Online (Sandbox Code Playgroud)
它失败并出现以下异常:
java.lang.IllegalStateException: An OAuth 2 access token must be obtained or an exception thrown.
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:124)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
Run Code Online (Sandbox Code Playgroud)
看起来http://localhost:%d/api/oauth/token端点现在是安全的,无法访问
这是我的配置:
OAuth2ServerConfig
@Configuration
public class OAuth2ServerConfig {
public …Run Code Online (Sandbox Code Playgroud) 实施不可知的讨论.
我假设当用户使用auth服务器进行身份验证时,客户端已获得访问令牌.选择哪个流(隐式,授权代码,密码)是无关紧要的.我想从客户端已经获得访问令牌的角度开始讨论.
从那时起,我很清楚当客户端需要访问单个资源服务器时会发生什么.
因此,在该图中,如果客户端要访问"StandAlone Service"(它不与任何其他资源服务器通信),那么流程对我来说很清楚.
当客户端跟随图中的红线时,我遇到了麻烦.所以我需要访问一个服务(资源服务器),以便回复需要访问另一个服务(也是资源服务器).在这种情况下,流程如何?
场景1.
我认为这里的问题是我放弃了用户权限.我将使用"订单服务"权限而不是用户的权限执行对"数据服务"的请求.
情景2.
在这里,我执行用户的权限,但现在我看到我的"数据服务"已公开,并对任何其他服务开放.(实际上我不知道oauth2是否提供了这样的限制.仅将客户端限制为特定的资源服务器)
场景3.
在这里,我看到了上述场景的组合,其中"订单服务"将为数据服务提供两种令牌.用户访问令牌,以便使用正确的权限和"订单服务"客户端访问令牌执行请求,以便我知道该服务可以与"数据服务"通信.
履行
我正在使用spring boot和spring security来设置我上面看到的oauth2组件.我已经有一个auth服务器,一个资源服务器和一个客户端.客户端此时与资源服务器进行通信,而不会将请求委托给另一个资源服务器.
根据最佳方法,我将如何进入实施方面?我需要对资源服务器进行哪些更改才能使它们能够安全地相互通信?
感谢您的时间
我正在使用Spring Boot 1.5.9,并且有一个应用程序具有使用OAuth2客户端凭据的API,而formlogin用于在同一个Spring Boot应用程序中使用Thymeleaf的CMS.
为此,我有以下bean来配置表单登录:
@Configuration
public class WebSecurityGlobalConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// api security is handled elsewhere (See OAuth2ServerConfiguration)
.antMatchers("/api/**", "/oauth/**", "/management/**")
.permitAll()
// end api security
.anyRequest().hasRole(UserRole.ADMIN.name())
.and()
.formLogin().loginPage("/login")
.permitAll()
.and()
.logout().permitAll();
}
}
Run Code Online (Sandbox Code Playgroud)
因此,对于表单登录部分,我声明了与API,Oauth和/ management相关的所有内容(我application.properties为执行器端点设置的自定义上下文路径):
management.context-path=/management …Run Code Online (Sandbox Code Playgroud) 我使用Spring云网关时遇到问题
如果任何依赖项直接或递归调用spring-boot-starter-tomcat
它将无法工作,因为它将启动嵌入式tomcat服务器而不是Spring云网关使用的netty服务器
我开始通过排除这种依赖性来解决这个问题
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
Run Code Online (Sandbox Code Playgroud)
春云网关成功运作
但有时我想使用spring-cloud-starter-oauth2来使用@ EnableOAuth2Sso
我开始使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
Run Code Online (Sandbox Code Playgroud)
那时我面临着抛出异常的大问题
引起:java.lang.IllegalStateException:无法在类org.springframework.security.oauth2.config.annotation.web.configuration.OAuth2ClientConfiguration上内省带注释的方法......
引起:java.lang.NoClassDefFoundError:javax/servlet/Filter
我已经使用spring安全模块实现了OAuth2密码授权.我添加了自己的UserDetails实现和UserDetailsService(jdbc).我将用户注入我的控制器:
@AuthenticationPrincipal User user
Run Code Online (Sandbox Code Playgroud)
User是UserDetails的实现.现在我想添加更改用户数据的可能性而不刷新令牌.
我尝试用以下内容刷新主体:
User updatedUser = ...
Authentication newAuth = new UsernamePasswordAuthenticationToken(updatedUser, updatedUser.getPassword(), updatedUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(newAuth);
Run Code Online (Sandbox Code Playgroud)
但它不起作用,当我调用另一个控制器方法时,它返回旧的User对象.
有没有办法在没有刷新令牌的情况下更改用户数据?是否有任何解决方案使Spring安全性始终从数据库(而不是从Cache)加载用户数据?
我正在 Spring Boot + Security(版本 5)应用程序中为自定义 OAuth2 提供程序创建 OAuth2.0 客户端。
下面是application.properties包含所有配置的,并且在我的项目中没有额外的配置类。
spring.security.oauth2.client.registration.xxxxxxxxx.client-id=XXXXXXXXXX
spring.security.oauth2.client.registration.xxxxxxxxx.client-secret=XXXXXXXXXX
spring.security.oauth2.client.registration.xxxxxxxxx.scope=openid
spring.security.oauth2.client.registration.xxxxxxxxx.redirect-uri-template=http://localhost:8080/login/oauth2/code/xxxxxxxxx
spring.security.oauth2.client.registration.xxxxxxxxx.client-name=xxxxxxxxx
spring.security.oauth2.client.registration.xxxxxxxxx.provider=xxxxxxxxx
spring.security.oauth2.client.registration.xxxxxxxxx.client-authentication-method=basic
spring.security.oauth2.client.registration.xxxxxxxxx.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.xxxxxxxxx.authorization-uri=https://api.xxxxxxxxx.com/authorize
spring.security.oauth2.client.provider.xxxxxxxxx.token-uri=https://api.xxxxxxxxx.com/token
spring.security.oauth2.client.provider.xxxxxxxxx.user-info-uri=https://api.xxxxxxxxx.com/userinfo?schema=openid
spring.security.oauth2.client.provider.xxxxxxxxx.user-name-attribute=name
spring.security.oauth2.client.provider.xxxxxxxxx.user-info-authentication-method=header
Run Code Online (Sandbox Code Playgroud)
当我点击http://localhost:8080/它时,它会正确重定向到提供商的登录页面,成功登录后它会重定向回我的应用程序。
我已经用谷歌搜索了这个错误,但没有得到任何正确的答案。此外,OAuth2 提供商没有共享此类 URL。
经过研究,我发现我需要设置以下属性。应该由Auth Provider 提供吗?
spring.security.oauth2.client.provider.pepstores.jwk-set-uri
我在配置中到底缺少什么?
我正在用 Angular 开发 SPA 应用程序,对于实现身份验证和授权的正确方法有很多困惑。
首先,该应用程序是第一方应用程序,这意味着我正在开发授权服务器和资源服务器。
登录应用程序的用户必须拥有对其平台上资源的完全访问权限。
因此,我使用 OAuth2.0 来完成此操作,并且我对该协议的域以及安全问题有一些疑问。
第一个问题:
第一个问题是 OAuth 是否应该实际用于授权第一方应用程序。据我了解,这是一种委托协议,用于在用户同意的情况下授予第三方应用程序对平台上用户资源的受控访问权限。这如何适合第一方应用程序的环境?在这种情况下,应用程序应该获得一个访问令牌,其范围允许完全访问,对吗?
第二个问题:
由于这是一个单页应用程序,我无法在客户端存储秘密。因此,我选择使用 PKCE 的授权代码授予,这似乎适合管理这种情况。在这种情况下,我不会要求刷新令牌,但我只会检索访问令牌并使用静默检查来刷新它。我不想将刷新令牌不安全地存储在浏览器上。这个PKCE真的安全吗?该秘密是动态生成的,但攻击者最终可以使用相同的公共客户端 ID 创建一个系统并正确管理 PKCE,并最终获得一个访问令牌,在我的例子中,该令牌可以完全访问用户资源。
我将来可以允许第三方应用程序对我的应用程序资源进行受控访问,这也是我坚持使用 OAuth 的原因之一。
spring-oauth2 ×10
spring ×4
java ×3
oauth-2.0 ×3
spring-boot ×3
oauth ×2
oauth2client ×2
security ×2
spring-mvc ×2
forgerock ×1
openam ×1