Keycloak implements permission control for Spring Boot applications in a few simple steps

We initially tried keycloak in the last article , manually created a realm named felord.cn and created a user named felord under the realm . Let 's try the corresponding Spring Boot Adapter today to see how keycloak protects Spring Boot applications.

Follow and star  Code Farmer Xiaopang , and get relevant dry goods articles as soon as possible.

client

I believe that many students have used WeChat Open Platform and Ant Open Platform. First we need to register a client on these open platforms to obtain a set of credentials like username and password. Some are called appid and secret; some are called clientid and secret, both of which mean the same thing. In fact, keycloak is similar, and a client needs to be registered in the corresponding realm . The following figure not only clearly illustrates the relationship between Master realm and custom realm in keycloak , but also illustrates the relationship between users and clients in a realm .

Realm, client, user relationship diagram

We need to create a client in the realm of felord.cn :

Create a client in realm

After the creation, you will find that there is one more client of felord.cn:

realm client list

You can log in the created user through http://localhost:8011/auth/realms/felord.cn/account/.

Then we edit and configure the client spring-boot-client:

Fill in the redirect URL

For testing, here I only filled in the only required item in the settings tab to effectively redirect the URI, which means that all APIs of the client springboot-client will be controlled by permissions.

Role

Role-based permission control is the current mainstream permission control idea, and keycloak also adopts this approach. We need to create a role and grant the user felord created in the previous article. Let's create a simple role:

Create roles in keycloak

The role of keycloak is very powerful. In the following series of articles, Fat Brother will learn this concept in depth with you.

Roles are mapped to users

Then we assign the role base_user created above to the user felord:

Assign roles to users in realm

At this point, users, roles, and role mappings are all done, and the only thing left is to define resources on the client.

Get and refresh JWT

We can get the JWT pair logged in by the user in the following way:

POST /auth/realms/felord.cn/protocol/openid-connect/token HTTP/1.1
Host: localhost:8011
Content-Type: application/x-www-form-urlencoded

client_id=springboot-client&username=felord&password=123456&grant_type=password

will get:

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiS 省略",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAi 省略",
    "token_type": "Bearer",
    "not-before-policy": 0,
    "session_state": "2fc7e289-c86f-4f6f-b4d3-1183a9518acc",
    "scope": "profile email"
}

To refresh the Token, you only need to bring the refresh_token, and change the grant_type to refresh_token to refresh the Token. The following is the message requesting the refresh:

POST /auth/realms/felord.cn/protocol/openid-connect/token HTTP/1.1
Host: localhost:8011
Content-Type: application/x-www-form-urlencoded

client_id=springboot-client&grant_type=refresh_token&refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlYWE2MThhMC05Y2UzLTQxZWMtOTZjYy04MGQ5ODVkZjJjMTIifQ.eyJleHAiOjE2MjU3NjI4ODYsImlhdCI6MTYyNTc2MTA4NiwianRpIjoiZjc2MjVmZmEtZWU3YS00MjZmLWIwYmQtOTM3MmZiM2Q4NDA5IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDExL2F1dGgvcmVhbG1zL2ZlbG9yZC5jbiIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODAxMS9hdXRoL3JlYWxtcy9mZWxvcmQuY24iLCJzdWIiOiI0YzFmNWRiNS04MjU0LTQ4ZDMtYTRkYS0wY2FhZTMyOTk0OTAiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoic3ByaW5nYm9vdC1jbGllbnQiLCJzZXNzaW9uX3N0YXRlIjoiZDU2NmU0ODMtYzc5MS00OTliLTg2M2ItODczY2YyNjMwYWFmIiwic2NvcGUiOiJwcm9maWxlIGVtYWlsIn0.P4vWwyfGubSt182P-vcyMdKvJfvwKYr1nUlOYBWzQks

Note: The content-type of both requests is application/x-www-form-urlencoded.

Spring Boot client

Build a very traditional Spring Boot application, don't forget to bring the Spring MVC module, and then add the keycloak starter :

        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-boot-starter</artifactId>
            <version>14.0.0</version>
        </dependency>

The current keycloak version is 14.0.0.

Then write a Spring MVC interface casually:

/**
 * @author felord.cn
 * @since 2021/7/7 17:05
 */
@RestController
@RequestMapping("/foo")
public class FooController {

    @GetMapping("/bar")
    public String bar(){
        return "felord.cn";
    }

}

Next, we declare and define that only users with the base_user role in the felord.cn realm can access the /foo/bar interface. So where is the definition? We first define it statically in application.yml in spring boot , and then implement dynamic control later. The configuration is as follows:

keycloak:
# 声明客户端所在的realm
  realm: felord.cn
# keycloak授权服务器的地址
  auth-server-url: http://localhost:8011/auth
# 客户端名称
  resource: springboot-client
# 声明这是一个公开的客户端,否则不能在keycloak外部环境使用,会403
  public-client: true
# 这里就是配置客户端的安全约束,就是那些角色映射那些资源
  security-constraints:
# 角色和资源的映射关系。下面是多对多的配置方式 ,这里只配置base_user才能访问 /foo/bar
    - auth-roles:
        - base_user
      security-collections:
        - patterns:
            - '/foo/bar'

Then start the Spring Boot application and call http://localhost:8080/foo/bar in the browser, you will find that the browser will jump to the following address:

http://localhost:8011/auth/realms/felord.cn/protocol/openid-connect/auth?response_type=code&client_id=springboot-client&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Ffoo%2Fbar&state=20e0958d-a7a9-422a-881f-cbd8f25d7842&login=true&scope=openid

OIDC authentication authorization login

It is based on the authentication and authorization mode of OIDC (an enhanced version of OAuth 2.0). You can only get the correct response from /foo/bar if you fill in the username and password correctly.

Summarize

Please Note : This is a series of articles, please click #keycloak at the beginning of the article to view the existing chapters.

We implemented OIDC authentication and authorization and protected the interface in Spring Boot with only some configuration , which is really simple. However, after reading this article, you will have a lot of questions, because you don't know much about the OIDC protocol. This protocol is very important, and major manufacturers are using this protocol. The next article will give you supplementary lessons for this agreement.

Guess you like

Origin blog.csdn.net/m0_63437643/article/details/123794272