Java 如何使用KeyClope实现一个基于令牌访问的简单web服务?
我想创建一个web服务,它将以以下方式工作:Java 如何使用KeyClope实现一个基于令牌访问的简单web服务?,java,spring,spring-boot,keycloak,Java,Spring,Spring Boot,Keycloak,我想创建一个web服务,它将以以下方式工作: 客户端包含keydepeat并提供用户名和密码 KeyClope将访问令牌返回给客户端 使用该访问令牌,客户机访问由KeyClope保护的页面 我怎么做 我尝试的 步骤1:客户端获得访问令牌 private String getAccessToken() throws IOException { final CloseableHttpClient client = HttpClients.createDefault(); final
private String getAccessToken() throws IOException {
final CloseableHttpClient client = HttpClients.createDefault();
final List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
nameValuePairs.add(new BasicNameValuePair("client_id", "test-app"));
nameValuePairs.add(new BasicNameValuePair("username", "user1"));
nameValuePairs.add(new BasicNameValuePair("password", "user1"));
nameValuePairs.add(new BasicNameValuePair("grant_type", "password"));
try {
final HttpPost post = new HttpPost("http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token");
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/x-www-form-urlencoded");
final CloseableHttpResponse response = client.execute(post);
final int statusCode = response.getStatusLine().getStatusCode();
System.out.println(String.format("Result: %d", statusCode));
if (statusCode != 200) {
System.out.println("Something went wrong");
return null;
}
final String responseTxt = EntityUtils.toString(response.getEntity());
final JSONObject json = new JSONObject(responseTxt);
final String accessToken = json.getString("access_token");
return accessToken;
} finally {
try {
client.close();
} catch (final IOException exception) {
exception.printStackTrace();
}
}
}
当我这样做的时候,我会得到keydape的登录页面作为响应,而不是web服务的响应
如何配置web服务?
以下是实际的web服务:
@RestController
public class SampleRestController {
@RequestMapping("/test")
public String test() {
return "Hello, world!";
}
}
安全配置:
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider
= keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(
new SessionRegistryImpl());
}
@Override
public void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.antMatchers("/test*")
.hasRole("user")
.anyRequest()
.permitAll();
}
}
application.properties
:
server.port = 8090
spring.main.allow-bean-definition-overriding=true
keycloak.realm = myrealm
keycloak.auth-server-url = http://127.0.0.1:8080/auth
keycloak.ssl-required = external
keycloak.resource = test-app
keycloak.public-client=true
keycloak.security-constraints[0].authRoles[0]=user
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/test/*
当我发送一个头部带有访问令牌的请求时,为了得到“Hello,world!”响应,我需要做哪些更改
更新1:我发现问题的一部分——客户端配置错误。它应该是仅承载
但是现在我得到了响应仅承载应用程序不允许启动浏览器登录
更新2:通过以下服务配置,它可以工作
server.port = 8090
spring.main.allow-bean-definition-overriding=true
keycloak.realm = myrealm
keycloak.resource = test-app
keycloak.auth-server-url = http://127.0.0.1:8080/auth
keycloak.bearer-only = true
keycloak.ssl-required = external
keycloak.principal-attribute = preferred_username
您使用了不正确的流或目的地。如果您想使用登录名/密码,您可以选择其中的两个:
如果您确实需要使用auth令牌,那么可以使用实现自定义和自定义您的
OAuth2RestTemplate
。但这并不太容易我需要使用首先获取访问令牌(或代码)的流,然后使用该代码连接到应用程序。另请参阅我的更新1。如果要为beare配置KeyClope,而不是服务器,则需要将用于登录的KC客户端设置为公共或机密,而不仅仅是beare。仅承载客户端不打算在身份验证流中使用。您用来进行身份验证的流是直接访问授权,它用于兼容性,但是对于全新的应用程序,授权代码流更可取。顺便说一句,我在您的代码中看到了另一个问题,对于构建您使用的String.format(“承载%s”,accessToken))
,我想应该是String.format(“承载%s,accessToken))
;-)
server.port = 8090
spring.main.allow-bean-definition-overriding=true
keycloak.realm = myrealm
keycloak.resource = test-app
keycloak.auth-server-url = http://127.0.0.1:8080/auth
keycloak.bearer-only = true
keycloak.ssl-required = external
keycloak.principal-attribute = preferred_username