我正在尝试创建一个页面,其中包含可以通过某个客户端网页访问的一些用户数据。这让我想到了oauth2(授权代码)和Spring。目前,我正在根据https://github.com/dynamind/spring-boot-security-oauth2-minimal/以及此工作流https://techannotation.files.wordpress.com/2015/06/oauth2-0-authorization-code.png
为我的代码编写某种概念证据。我已经拥有一个资源服务器,它使用登录页面对用户进行身份验证,然后让他们可以通过某种方式批准共享他们的数据。然后,它将用户重定向到为客户端设置的页面。
@SpringBootApplication
public class AuthorizationServerApplication extends SpringBootServletInitializer {
private static final Logger log = LoggerFactory.getLogger(AuthorizationServerApplication.class);
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(AuthorizationServerApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AuthorizationServerApplication.class);
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Autowired // <-- This is crucial otherwise Spring Boot creates its own
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
log.info("Defining inMemoryAuthentication (2 users)");
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
.and()
.httpBasic().disable().anonymous().disable().authorizeRequests().anyRequest().authenticated();
}
}
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Value("${config.oauth2.privateKey}")
private String privateKey;
@Value("${config.oauth2.publicKey}")
private String publicKey;
@Autowired
private AuthenticationManager authenticationManager;
@Bean
public JwtAccessTokenConverter tokenEnhancer() {
log.info("Initializing JWT with public key:\n" + publicKey);
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(privateKey);
converter.setVerifierKey(publicKey);
return converter;
}
@Bean
public JwtTokenStore tokenStore() {
return new JwtTokenStore(tokenEnhancer());
}
/**
* Defines the security constraints on the token endpoints
* /oauth/token_key and /oauth/check_token Client credentials are
* required to access the endpoints
*
* @param oauthServer
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("isAnonymous() || hasRole('ROLE_TRUSTED_CLIENT')") // permitAll()
.checkTokenAccess("hasRole('TRUSTED_CLIENT')"); // isAuthenticated()
}
/**
* Defines the authorization and token endpoints and the token services
*
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
// Which authenticationManager should be used for the
// password grant
// If not provided, ResourceOwnerPasswordTokenGranter is not
// configured
.authenticationManager(authenticationManager)
// Use JwtTokenStore and our jwtAccessTokenConverter
.tokenStore(tokenStore()).accessTokenConverter(tokenEnhancer());
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
// Public client where client secret is vulnerable (e.g.
// mobile apps, browsers)
.withClient("clientname") // No secret!
.authorizedGrantTypes("authorization_code").scopes("read")
.redirectUris("http://localhost:8080/client")
;
}
}
}
目前我正在处理一个最简单的客户端网页。我创建了一个包含授权服务器链接的页面(localhost:8081 / oauth / authorize ...)。用户点击它并被重定向到授权服务器,在那里登录,批准共享他/她的数据,然后重定向回客户端站点(localhost:8080 /客户端,但授权服务器给出代码),但现在有额外的选项再单击一个已返回代码的链接(localhost:8081 / oauth / token ...)。所有这一切都有效,但是当用户单击此第二个链接并重定向到授权服务器时,此auth服务器会响应“访问此资源需要完全身份验证”。
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>client page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'oooo text oooo'" />
if you want it
<a
th:href="@{http://localhost:8081/oauth/authorize(response_type='code',client_id='client',key='value',scope='read',redirect_uri='http://localhost:8080/client')}">clickit</a>
<a th:if="${param.code != null}"
th:href="@{http://localhost:8081/oauth/token(grant_type='authorization_code',code=${param.code[0]},redirect_uri='http://localhost:8080/client')}">
approve
</a>
<div th:if=" ${param.code !=null}
"
th:text="${'requestParam: ' + param.code[0]}"></div>
</body>
</html>
你对这个问题有任何想法吗?
答案 0 :(得分:0)
原来是因为我没有使用POST请求。使用它解决了这个问题:
<form th:if="${param.code != null}"
th:method="post"
th:action="@{http://localhost:8081/oauth/token}">
<input type="text" id="grant_type" name="grant_type" th:value="authorization_code"/>
<input type="text" id="client_id" name="client_id" th:value="client"/>
<input type="text" id="code" name="code" th:value="${param.code[0]}"/>
<input type="text" id="redirect_uri" name="redirect_uri" th:value="@{http://localhost:8080/client}"/>
<input type="submit" />
</form>