下载和启动keycloak很容易,做测试用,下载后进入bin文件夹下直接用自带脚本standalone.bat启去就可以了
用 Keycloak UI 配置鉴权所需的client,role,user
创建rest-api的client
选择一个reaml后,点Clients --> Create
Access Type 选confidential
rest-api 不需要重定向 Valid Redirect URIs 随便写一个值
给rest-api创建角色
给rest-api 创建一个角色叫rest-api-user
创建用户api-user
创建一个叫api-user的用户
给api-user分配角色
切到 role mappings 选项卡 在client roles 搜索到自己的rest-api,选择角色,点击add selected
给api-user 设置密码
去掉 update password
在Required User Actions中关掉 update password点save
创建另一个client叫 rest-api-client 用于获取token访问应用
点击图中第1步再点创建后,
进入第2步选confidential
打开第3步Service Accounts Enabled开关
api没有页面第4步可以随意写
点击保存后会出现图中第5步的选项卡
给client 添加角色
1点service account roles选项卡后
2搜出rest-api
3选择role
4添加并保存
Get Token
配置完以上步骤可以来获取token了
1 用POST方法 访问 localhost:8080/auth/realms/cvc/protocol/openid-connect/token
2 body 格式选 application/x-www-form-urlencoded 添加参数
#client
grant_type:client_credentials
client_id:rest-api-client
client_secret:9fa7a96c-c9d5-485c-91b5-ec08d5af0542
#user
grant_type:password
username:api-user
password:12345
client_id:rest-api-client
把token复制到jwt.io中可以解析看到角色
SpringBoot编写
创建SpringBoot项目
添加库
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<version>7.0.0</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>7.0.0</version>
</dependency>
增加RestController
@RestController
public class HomeController {
private final HttpServletRequest request;
@Autowired
public HomeController(HttpServletRequest request) {
this.request = request;
}
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
配置类
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class KeycloakConfig {
@Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.keycloak.adapters.springsecurity.management.HttpSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@KeycloakConfiguration
public class KeycloakSecurityConfigurer extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
grantedAuthorityMapper.setPrefix("ROLE_");
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
// return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
return new NullAuthenticatedSessionStrategy();
}
@Bean
@Override
@ConditionalOnMissingBean(HttpSessionManager.class)
protected HttpSessionManager httpSessionManager() {
return new HttpSessionManager();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
.antMatchers("/hello*").hasAnyRole( "rest-manager", "rest-api-user")
.anyRequest().permitAll()
.and().csrf().disable();
}
}
application配置文件
keycloak:
auth-server-url: http://localhost:8080/auth
disable-trust-manager: true
principal-attribute: preferred_username
public-client: false
realm: cvc
resource: reactor-manager
use-resource-role-mappings: true
keycloak的地址如果是不受信任的https(如自签名ssl)可以设置
disable-trust-manager=true
来访问
开启keycloak.use-resource-role-mappings=true
配置后就是要配置到client下面role去验证
配置文件的一些可选项可参考文档:
https://www.keycloak.org/docs/latest/securing_apps/#java-adapters
{
"resource_access": {
"rest-api": {
"roles": [
"rest-api-user"
]
}
从jwt解析可以看到token拥有client为rest-api下的rest-api-user的role
验证api保护
把token填写到 token处
开启 service_accounts
https://www.keycloak.org/docs/latest/server_admin/index.html#_service_accounts
配置 java-adapter
https://www.keycloak.org/docs/latest/securing_apps/#java-adapters