Okta的Spring安全

Spring Security With Okta

1.概述

Okta为Web,移动或API服务提供了身份验证,授权和社交登录等功能。 此外,它对Spring框架提供了强大的支持,使集成变得非常简单。

现在,Stormpath与Okta联手为开发人员提供了更好的Identity API,这已成为在Web应用程序中启用身份验证的一种流行方法。

在本教程中,我们将使用Okta探索Spring Security,以及Okta开发人员帐户的简约设置。

2.设置Okta

2.1。 开发人员帐户注册

首先,我们将注册一个免费的Okta开发者帐户,该帐户可提供多达1000个每月活跃用户的访问权限。 但是,如果已经有一个,则可以跳过本节:

 width=

2.2。 仪表板

登录到Okta开发人员帐户后,我们将进入仪表板屏幕,该屏幕向我们简要介绍用户数量,身份验证和登录失败。

此外,它还显示系统的详细日志条目:

 width=

此外,我们会在仪表板的右上角记下组织URL,这是我们稍后创建的Spring Boot App中Okta设置所必需的。

2.3。 创建一个新的应用程序

然后,让我们使用"应用程序"菜单创建一个新应用程序,以为Spring Boot创建OpenID Connect(OIDC)应用程序。

此外,我们将从可用选项(例如本机,单页应用和服务)中选择Web平台:

 width=

2.4。 应用程序设置

接下来,让我们配置一些应用程序设置,例如指向我们应用程序的基本URI和登录重定向URI:

 width=

另外,请确保为允许对Web应用程序启用OAuth2身份验证所需的Grant类型标记为授权代码。

2.5。 客户凭证

然后,我们将获取与我们的应用程序关联的Client ID和Client secret的值:

 width=

请妥善保管这些凭据,因为Okta设置需要它们。

3. Spring Boot应用设置

现在我们的Okta开发人员帐户已准备好基本配置,我们准备将Okta安全支持集成到Spring Boot App中。

3.1。 马文

首先,让我们将最新的okta-spring-boot-starter Maven依赖项添加到我们的pom.xml中:

1
2
3
4
5
<dependency>
    <groupId>com.okta.spring</groupId>
    <artifactId>okta-spring-boot-starter</artifactId>
    <version>1.4.0</version>
</dependency>

3.2。 摇篮

同样,当使用Gradle时,我们可以在build.gradle中添加okta-spring-boot-starter依赖项:

1
compile 'com.okta.spring:okta-spring-boot-starter:1.4.0'

3.3。 application.properties

然后,我们将在application.properties中配置Okta oauth2属性:

1
2
3
4
okta.oauth2.issuer=https://dev-example123.okta.com/oauth2/default
okta.oauth2.client-id=1230oaa4yncmaxaQ90ccJwl4x6
okta.oauth2.client-secret=hjiyblEzgT0ItY91Ywcdzwa78oNhtrYqNklQ5vLzvruT123
okta.oauth2.redirect-uri=/authorization-code/callback

在这里,我们可以将默认授权服务器(如果没有可用的话)用于指向{orgURL} / oauth2 / default的颁发者URL

另外,我们可以使用API菜单在Okta开发人员帐户中创建新的授权服务器:

 width=

然后,我们将添加上一部分中生成的Okta应用程序的"客户端ID"和"客户端密码"。

最后,我们已经配置了与"应用程序设置"中设置的相同的redirect-uri。

4. HomeController

之后,让我们创建HomeController类:

1
2
3
4
5
6
7
@RestController
public class HomeController {
    @GetMapping("/")
    public String home(@AuthenticationPrincipal OidcUser user) {
        return"Welcome,"+ user.getFullName() +"!";
    }
}

在这里,我们添加了具有Base Uri(/)映射的home方法,该映射在"应用程序设置"中配置。

另外,home方法的参数是OidcUser的实例

而已! Okta安全支持已准备好我们的Spring Boot App。 让我们使用Maven命令运行我们的应用程序:

1
mvn spring-boot:run

在localhost:8080访问应用程序时,我们将看到Okta提供的默认登录页面:

 width=

使用注册用户的凭据登录后,将显示带有用户全名的欢迎消息:

 width=

另外,我们会在默认登录屏幕底部找到一个"注册"链接,以进行自我注册。

5.注册

5.1。 自我注册

第一次,我们可以使用"注册"链接创建一个Okta帐户,然后提供诸如电子邮件,名字和姓氏之类的信息:

 width=

5.2。 创建一个用户

或者,我们可以从Okta开发人员帐户的"用户"菜单中创建一个新用户:

 width=

5.3。 自助服务注册设置

此外,可以从Okta开发人员帐户的"用户"菜单中配置注册和注册设置:

 width=

6. Okta Spring SDK

既然我们已经在Spring Boot应用程序中看到Okta安全集成,那么让我们与同一应用程序中的Okta管理API进行交互。

首先,我们应该使用Okta开发人员帐户中的API菜单创建令牌:

 width=

确保记下令牌,因为令牌在生成后仅显示一次。 然后,将其存储为哈希值以保护我们。

6.1。 建立

然后,让我们添加最新的okta-spring-sdk

1
2
3
4
5
<dependency>
    <groupId>com.okta.spring</groupId>
    <artifactId>okta-spring-sdk</artifactId>
    <version>1.4.0</version>
</dependency>

6.2。 application.properties

接下来,我们将添加一些基本的Okta客户端属性:

1
2
okta.client.orgUrl=https://dev-example123.okta.com
okta.client.token=00TVXDNx1e2FgvxP4jLlONbPMzrBDLwESSf9hZSvMI123

在这里,我们添加了上一节中提到的令牌。

6.3。 管理员控制器

最后,让我们创建AdminController,并将其注入客户端

1
2
3
4
5
@RestController
public class AdminController {
    @Autowired
    public Client client;
}

而已! 我们准备在Client实例上调用方法以向Okta API发出请求。

6.4。 列出用户

让我们创建一个getUsers方法,以使用返回UserList的listUsers方法来获取组织中所有用户的列表。

1
2
3
4
5
6
7
8
public class AdminController {
    // ...

    @GetMapping("/users")
    public UserList getUsers() {
        return client.listUsers();
    }
}

之后,我们可以访问localhost:8080 / users

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
   "dirty":false,
   "propertyDescriptors":{
       "items":{
           "name":"items",
           "type":"com.okta.sdk.resource.user.User"
        }
    },
   "resourceHref":"/api/v1/users",
   "currentPage":{
       "items":[
            {
               "id":"00uanxiv7naevaEL14x6",
               "profile":{
                   "firstName":"Anshul",
                   "lastName":"Bansal",
                   "email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="43222d302b362f0321222d30222f6d202c2e">[emailprotected]</a>",
                    // ...
                },
                // ...
            },
           {
               "id":"00uag6vugXMeBmXky4x6",
               "profile":{
                   "firstName":"Ansh",
                   "lastName":"Bans",
                   "email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="066768756e46646768752865696b">[emailprotected]</a>",
                    // ...
                },
                // ...
            }
        ]
    },
   "empty":false,
    // ...
}

6.5。 搜索用户

同样,我们可以使用firstName,lastName或email作为查询参数来过滤用户:

1
2
3
4
@GetMapping("/user")
public UserList searchUserByEmail(@RequestParam String query) {
    return client.listUsers(query, null, null, null, null);
}

让我们使用本地主机通过电子邮件搜索用户:8080 / [已受电子邮件保护]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
   "dirty":false,
   "propertyDescriptors":{
       "items":{
           "name":"items",
           "type":"com.okta.sdk.resource.user.User"
        }
    },
   "resourceHref":"/api/v1/users?q=ansh%40bans.com",
   "currentPage":{
       "items":[
            {
               "id":"00uag6vugXMeBmXky4x6",
               "profile":{
                   "firstName":"Ansh",
                   "lastName":"Bans",
                   "email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bddcd3ced5fddfdcd3ce93ded2d0">[emailprotected]</a>",
                    // ...
                },
                // ...
            }
        ]
    },
    // ...
}

6.6。 创建用户

另外,我们可以使用UserBuilder的instance方法创建一个新用户

1
2
3
4
5
6
7
8
9
10
11
12
@GetMapping("/createUser")
public User createUser() {
    char[] tempPassword = {'P','a','$','$','w','0','r','d'};
    User user = UserBuilder.instance()
        .setEmail("<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="076968756a666b296b62706e7447626a666e6b2964686a">[emailprotected]</a>")
        .setFirstName("Norman")
        .setLastName("Lewis")
        .setPassword(tempPassword)
        .setActive(true)
        .buildAndCreate(client);
    return user;
}

因此,让我们访问localhost:8080 / createUser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
   "id":"00uauveccPIYxQKUf4x6",  
   "profile": {
       "firstName":"Norman",
       "lastName":"Lewis",
       "email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cda3a2bfa0aca3e3a1a8baa4be8da8a0aca4a1e3aea2a0">[emailprotected]</a>"
    },
   "credentials": {
       "password": {},
       "emails": [
            {
               "value":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="99f7f6ebf4f8f7b7f5fceef0ead9fcf4f8f0f5b7faf6f4">[emailprotected]</a>",
               "status":"VERIFIED",
               "type":"PRIMARY"
            }
        ],
        // ...
    },
   "_links": {
       "resetPassword": {
           "href":"https://dev-example123.okta.com/api/v1/users/00uauveccPIYxQKUf4x6/lifecycle/reset_password",
           "method":"POST"
        },
        // ...
    }
}

同样,我们可以执行一系列操作,例如列出所有应用程序,创建应用程序,列出所有组以及创建组。

7.结论

在本快速教程中,我们使用Okta探索了Spring Security。

首先,我们使用基本配置设置Okta开发人员帐户。 然后,我们创建了一个Spring Boot App,并配置了application.properties以便与Okta进行Spring Security集成。

接下来,我们集成了Okta Spring SDK来管理Okta API。 最后,我们研究了列出所有用户,搜索用户以及创建用户的功能。

像往常一样,所有代码实现都可以在GitHub上获得。