keycloak应用于保护rest资源

keycloak配置

创建一个realm

PJ1COf.png

创建两个role

PJ1QmT.png

创建两个user,他别属于两个role

user001属于user,user002属于user_pre和user,并将他们的密码都设为1 
PJ12ct.png

创建一个client,

PJ1H9s.png
并指定重定向uri,开启授权,别忘了保存 
PJ3Au6.png 
然后选中authorization,接下来我们来设置三个东西:resource,policy,permission 
PJ3lvt.png

  • resource的设置 
    创建一个resource:api resource 
    PJ36VU.png
    PJ3WG9.png
    同理,再创一个资源apj resource,uri

  • policy设置 
    创建一个policy:api policy 
    PJ3Ir6.png
    把user加入到api policy中 
    PJ3LPH.png
    同理,再创一个policy:apj policy,把user_pre加其中

permission的设置 
创建一个permission:api permission 
将api resource加入resource,api policy加入policy 
PJ8PIg.png
PJ8ZMq.png
同理,理创一个apj permission,将apj resource 和apj policy 分别加入其中

至此,keycloak配置已经结束了,我们来总结一下: 
demo2-cli里面定义重定向地址是我们的资源位置,有两个资源:api resource和apj resource,user001 和user002 分别有资格访问这两个资源(通达pemission次resource和policy联系)

java springboot端

这里要注意的是secret字段,后面说,真是一个大坑

 

properties

  1. server.port=8081
  2.  
  3.  
  4. keycloak.realm=demo2
  5. keycloak.auth-server-url=http://localhost:8080/auth
  6. keycloak.ssl-required=external
  7. keycloak.resource=demo2-cli
  8. keycloak.bearer-only=true
  9. keycloak.credentials.secret=e17b7d66-7218-47b9-94c0-df77810e6559
  10. keycloak.securityConstraints[0].authRoles[0]=user
  11. keycloak.securityConstraints[0].securityCollections[0].name=protected
  12. keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/*
  13. keycloak.policy-enforcer-config.on-deny-redirect-to=/accessDenied
 

pom

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6.  
  7. <groupId>com.example</groupId>
  8. <artifactId>demo-keycloak-2.0.2-rest</artifactId>
  9. <version>0.0.1-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11.  
  12. <name>demo-keycloak-2.0.2-rest</name>
  13. <description>Demo project for Spring Boot</description>
  14.  
  15. <parent>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-starter-parent</artifactId>
  18. <version>2.0.2.RELEASE</version>
  19. <relativePath /> <!-- lookup parent from repository -->
  20. </parent>
  21.  
  22. <properties>
  23. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  24. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  25. <java.version>1.8</java.version>
  26. </properties>
  27.  
  28. <dependencies>
  29.  
  30. <!-- keycloak -->
  31. <dependency>
  32. <groupId>org.keycloak</groupId>
  33. <artifactId>keycloak-spring-boot-starter</artifactId>
  34. <version>4.1.0.Final</version>
  35. </dependency>
  36. <dependency>
  37. <groupId>org.springframework.boot</groupId>
  38. <artifactId>spring-boot-starter-web</artifactId>
  39. </dependency>
  40.  
  41. <dependency>
  42. <groupId>org.springframework.boot</groupId>
  43. <artifactId>spring-boot-starter-test</artifactId>
  44. <scope>test</scope>
  45. </dependency>
  46. </dependencies>
  47.  
  48. <build>
  49. <plugins>
  50. <plugin>
  51. <groupId>org.springframework.boot</groupId>
  52. <artifactId>spring-boot-maven-plugin</artifactId>
  53. </plugin>
  54. </plugins>
  55. </build>
  56. </project>

controller

 
  1. package com.example.demo.web;
  2.  
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RequestMethod;
  5. import org.springframework.web.bind.annotation.RestController;
  6.  
  7. @RestController
  8. public class ApplicationController {
  9. @RequestMapping(value = "/api/resourcea", method = RequestMethod.GET)
  10. public String handleResourceA() {
  11. return "Access Granted in my own demo api a";
  12. }
  13.  
  14. @RequestMapping(value = "/api/resourceb", method = RequestMethod.GET)
  15. public String handleResourceAB() {
  16. return "Access Granted in my own demo api b";
  17. }
  18.  
  19. @RequestMapping(value = "/apj/resourceb", method = RequestMethod.GET)
  20. public String handleResourceB() {
  21. return "Access Granted in my own demo apj b";
  22. }
  23. }

java端的就这么多,接下来就是应用了。如果这时启动springboot,浏览器访问我们的资源时会提示无权限 
PJYYyn.png
原因是无token. 
下面的请求我们用postman处理

浏览器端(postman)模拟

这里我们先看一下client端的secret 
PJY0FU.png
这个secret要与properties里的secret字段相同,否则会出错 
1.向浏览器发送请求:http://localhost:8080/auth/realms/demo2/.well-known/uma2-configuration 
这里的demo2就是我们前面在keycloak里创建的demo2 
获得:

 
  1. {
  2. "issuer": "http://localhost:8080/auth/realms/demo2",
  3. "authorization_endpoint": "http://localhost:8080/auth/realms/demo2/protocol/openid-connect/auth",
  4. "token_endpoint": "http://localhost:8080/auth/realms/demo2/protocol/openid-connect/token",
  5. "token_introspection_endpoint": "http://localhost:8080/auth/realms/demo2/protocol/openid-connect/token/introspect",
  6. "end_session_endpoint": "http://localhost:8080/auth/realms/demo2/protocol/openid-connect/logout",
  7. "jwks_uri": "http://localhost:8080/auth/realms/demo2/protocol/openid-connect/certs",
  8. "grant_types_supported": [
  9. "authorization_code",
  10. "implicit",
  11. "refresh_token",
  12. "password",
  13. "client_credentials"
  14. ],
  15. "response_types_supported": [
  16. "code",
  17. "none",
  18. "id_token",
  19. "token",
  20. "id_token token",
  21. "code id_token",
  22. "code token",
  23. "code id_token token"
  24. ],
  25. "response_modes_supported": [
  26. "query",
  27. "fragment",
  28. "form_post"
  29. ],
  30. "registration_endpoint": "http://localhost:8080/auth/realms/demo2/clients-registrations/openid-connect",
  31. "token_endpoint_auth_methods_supported": [
  32. "private_key_jwt",
  33. "client_secret_basic",
  34. "client_secret_post",
  35. "client_secret_jwt"
  36. ],
  37. "token_endpoint_auth_signing_alg_values_supported": [
  38. "RS256"
  39. ],
  40. "scopes_supported": [
  41. "openid",
  42. "address",
  43. "email",
  44. "offline_access",
  45. "phone",
  46. "profile"
  47. ],
  48. "resource_registration_endpoint": "http://localhost:8080/auth/realms/demo2/authz/protection/resource_set",
  49. "permission_endpoint": "http://localhost:8080/auth/realms/demo2/authz/protection/permission",
  50. "policy_endpoint": "http://localhost:8080/auth/realms/demo2/authz/protection/uma-policy"
  51. }

有图为证: 
PJYcO1.png
我们要的就是token_endpoint后面的这个链接 
http://localhost:8080/auth/realms/demo2/protocol/openid-connect/token 
2.获取token 
打开OAuth2.0授权框 
PJY76A.png
进入 
PJtQn1.png
选密码授权 
PJtGtO.png 
进入后有三个地方要改:tokenURL就是我们前面token endpoint那个url,填用户名密码,还有client Secret就是我们keycloak中demo2-cli的secret,最后再RequestToken就可以了PJtN1H.png 
我们可以得到一个token,这个就是我们忙了半天最后要的东西,它可以让我们访问登录用户相应的资源。 
PJTqRU.png
接下来我们把得到的token通过请求头带过去就可以访问相应的资源了,看一图 
PJTjsJ.png
这里的Barer是一个固定值,它+空格+token构成键Authorize的值,我们看到确实是可以访问的,由于我们登录的是user002,所以访问的是apj/resourceb,我们试试api/resourcea行不行。 
PJ7Sd1.png
可以看到是403未授权错识,这次我们用user001来获取token再访问api/resourcea试试 
PJ7AQe.png
这里我用通过user001获取的token来替代了原来的token,可以看到api/resourcea可以访问了。

  • 注意两点: 
    1、properties里面设置了访问角色控制,因此user002同时有user和user-pre角色 
    2、将得到的token复制过去后注意最后一行有时会有多余的空格,有的话要删去,否则会有SSL错误

springboot端资源源码

猜你喜欢

转载自blog.csdn.net/hb_688/article/details/81180709