永不再构建身份验证 –喜欢构建用户管理? 使用Okta,您可以在几分钟内为您的应用程序添加社交登录,多因素身份验证和OpenID Connect支持。 立即创建一个免费的开发者帐户。

在构建Java应用程序时,用户管理是至关重要的考虑因素。 应用程序和API通常会根据分配给用户的角色来划分对应用程序不同部分的访问权限-这是基于角色的访问控制(RBAC)。

这就是Okta的用处– Okta通过管理组内的角色(用户可以属于一个或多个组)来简化此过程。 借助Okta的Spring Security集成,该过程通过使用将组映射到特定角色并允许或拒绝访问的通用注释而变得自动化。 这是使用常见的Spring Security注释完成的,我们在下面对此进行了概述。

为了在实践中展示这一点,我在下面整理了一个演示,演示了一个简单但常见的场景。 在我们的示例中,我们将查看未受保护的页面,只有经过身份验证的用户才能访问的页面以及要求用户在访问它们之前必须具有额外授权级别的页面的混合。

我们在这里添加了我们引用的所有代码。

如果您已经打算开始使用Java应用程序的内置RBAC并开始使用它,只需在此处将Okta租户连接到Spring Boot应用程序即可。

如有任何疑问,请在此处联系Okta的开发支持团队。

第一步:配置您的Okta帐户

第一步是设置Okta租户。 这样,您可以启动我们创建的示例应用程序,并在实际中看到它。 在此处注册开发者帐户,然后按照以下步骤操作:

  1. 创建一个admins
  2. 创建一个users
  3. 创建属于users组的users
  4. 创建属于两个组的第二个用户
  5. 创建一个OpenID Connect(OIDC)应用程序
  6. 将两个组添加到应用程序
  7. 配置默认的授权服务器以在访问令牌中包括组成员身份

让我们来看一下它是什么样的:

设置组

在您的Okta管理员仪表板菜单中,找到“ Users ,然后单击“ Groups 。 单击Add Group然后在Name字段中输入admins ,然后添加组描述,例如:管理员。 单击Add Group以完成此步骤。

按照相同的过程添加users组。

设置用户

再次,在Okta Admin仪表板中导航至Users ,但这一次单击People 。 单击Add User然后在表单中填写用户信息。 (将真实的电子邮件地址用作主电子邮件地址或辅助电子邮件地址,以及您可以访问的电子邮件地址,以便以后可以验证电子邮件。)在“ Groups字段中,将此用户添加到您先前创建的users组中。 确保已单击Send user activation email now复选框,然后单击“保存并添加另一个”。

我们重复上述步骤,只是这一次,第二用户添加到两个 usersadmins组。

跳到您的电子邮件并验证这些电子邮件地址。 单击两个用户的链接以激活它们。

创建一个OIDC应用程序

现在是时候设置您的身份验证层了。

在Okta Admin仪表盘中,单击菜单中的Applications ,然后单击Add Application

选择Web ,然后单击Next

当提示您填写表格时,请使用以下值:

| Field               | Value                          |
| ------------------- | ------------------------------ |
| Name                | Fun with Spring Security Roles |
| Base URIs           | http://localhost:8080/         |
| Login redirect URIs | http://localhost:8080/         |
| Group assignments   | `admins` and `users`           |
| Grant type allowed  | Check: `Implicit`              |

准备就绪后,单击“完成”,您将在下面看到结果页面:

小费
指定的URI是Spring Boot的默认值。 您以后可以轻松更改它们。

继续进行下一步之前,向下滚动并记下Client ID 。 您将需要它来配置Spring Boot应用程序。

设置授权服务器

接下来,在Okta管理员仪表板菜单中查找API ,然后单击Authorization Servers以启动以下命令:

记下Issuer URI 。 稍后您还将需要此配置Spring Boot应用程序。

单击default然后选择“ Claims选项卡。 单击Add Claim然后按如下所示填写字段:

| Field                 | Value        |
| --------------------- | ------------ |
| Name                  | groups       |
| Include in token type | Access Token |
| Value type            | Groups       |
| Filter                | Regex .*     |
| Include in            | Any scope    |

单击Create以完成此步骤。

创建此声明可确保在用户进行身份验证时将组成员身份信息包括在访问令牌中。 这一步对于了解Spring Security的角色和权限机制至关重要。

第二步:配置您的Spring Boot应用

首先,在此链接处克隆。

在首选的IDE或编辑器中打开项目。 下面的截图来自这里。

复制application.yml.sample文件并将其命名为application.yml

还记得我们标记要保存的那些值吗? 使用这些更新您的信息。 这是我们的示例:

| Name        | Value                                             |
| ----------- | ------------------------------------------------- |
| baseUrl     | https://dev-237330.oktapreview.com                |
| issuer      | https://dev-237330.oktapreview.com/oauth2/default |
| audience    | api://default                                     |
| clientId    | 0oacdldhkydGGruON0h7                              |
| rolesClaim  | groups                                            |
| redirectUri | http://localhost:8080/                            |

在进入代码之前,让我们看看实际的应用程序。

从命令行运行此命令以开始操作:

mvn spring-boot:run

查看实际应用

导航到主页,然后单击“ Login

要登录,请使用属于您在第一步中创建的“ Users组的用户的凭据。 从那里,您将看到该应用程序显示您的用户信息,并在其下方显示一行按钮。

这些与应用程序内的访问权限相对应。 单击“ Users Only时, users组的成员将能够看到该页面。 对于admins组的用户,情况相同,单击“ Admins Only时可以看到该页面。

让我们看看它是如何工作的。

单击Users Only 。 您会看到一个页面,显示您是users组的成员。
单击上Back ,然后单击Admins Only 。 这次,您将获得403 Unauthorized页面,因为您不是admins组的成员。
单击Logout并再次登录,但是这次是属于两个组的用户(您在步骤1中创建的第二个用户)。 单击Admins Only

这次,您将看到您同时属于adminsusers组。

很简单! 现在,让我们跳入代码...

第三步:Spring安全代码审查

本节概述Okta组如何链接到Spring Security角色。

该演示应用程序使用以下内容:

  1. Spring靴
  2. Spring安全
  3. Spring安全OAuth2
  4. Okta Spring安全入门
  5. 胸腺模板
  6. Spring安全4的Thymeleaf Extras
  7. Okta登录小部件

我们依赖okta-spring-security-starter (来自pom.xml)。 这就是幕后魔术的发生方式:

...
<dependency><groupId>com.okta.spring</groupId><artifactId>okta-spring-security-starter</artifactId><version>0.1.0</version>
</dependency>
...

让我们从Javascript Okta登录小部件开始,看看它如何将客户端连接到Spring Boot。

设置Okta登录小部件

这是我们在`login.html` Thymeleaf模板中设置Okta登录小部件的方式:

$( document ).ready(function() {var data = {baseUrl: [[${appProperties.baseUrl}]],clientId: [[${appProperties.clientId}]],redirectUri: [[${appProperties.redirectUri}]],authParams: {issuer: [[${appProperties.issuer}]],responseType: ['token']}};window.oktaSignIn = new OktaSignIn(data);// Check if we already have an access tokenvar token = oktaSignIn.tokenManager.get('token');if (token) {window.location.href = "/authenticated";} else {renderWidget();}
});

在第3-8行中,您将看到我们已经嵌入了所有设置以作为嵌入式Thymeleaf Template变量连接到Okta租户。 这些值从Spring Boot控制器作为模型的一部分传入。 这样,您只需指定一次这些设置-现在服务器端和客户端都可以确保它们。 我们将在下面详细说明如何管理这些设置(它们全部来自application.yml文件)。

在配置并实例化Okta登录小部件之后,下一步是检查用户是否已登录。然后执行以下两个操作之一。 如果有,我们将其发送到/authenticated页面。 如果还没有,我们将渲染小部件,这将为用户提供登录的机会。

这是renderWidget函数:

function renderWidget() {oktaSignIn.renderEl({el: '#okta-login-container'},function (response) {// check if successif (response.status === 'SUCCESS') {// for our example we have the id token and the access tokenoktaSignIn.tokenManager.add('token', response[0]);if (!document.location.protocol.startsWith('https')) {console.log('WARNING: You are about to pass a bearer token in a cookie over an insecure\n' +'connection. This should *NEVER* be done in a production environment per\n' +'https://tools.ietf.org/html/rfc6750');}document.cookie = 'access_token=' + oktaSignIn.tokenManager.get('token').accessToken;document.location.href = "/authenticated";}},function (err) {// handle any errorsconsole.log(err);});
}

在窗口小部件上呈现了窗口小部件之后,内部逻辑将根据用户登录时的设置来接管。在这种情况下,您正在使用此流,并且仅获取由配置的responseType参数指定的访问令牌。 。

成功登录后,您将输入带有response对象的回调函数。 响应对象具有您的访问令牌(在本例中为您用户的访问令牌)。

第19行使用访问令牌设置cookie,第20行将(现在已认证的)用户发送到/authenticated端点。

此时,Spring Security可以识别经过身份验证的用户。

在介绍Spring Security角色之前,让我们看一下Spring Security如何处理访问令牌。

Spring Security令牌提取器

默认情况下,Spring Security OAuth 2.0插件处理进入Authorization标头中的访问令牌作为承载令牌。 这对于为客户端(例如Angular客户端)创建RESTful响应的应用程序很好。

对于此示例,我将Javascript的体系结构和数量保持在最低限度,因此我希望进行完整的页面转换。 这有点老套了,但是它使示例代码紧凑而紧凑。

为了使Spring Security能够识别用户已通过身份验证,我们需要它能够处理进入cookie的令牌。

幸运的是,通过设置TokenExtractor ,Spring Security使覆盖默认行为变得非常容易。 这是从OktaSpringSecurityRolesExampleApplication实现此目的的代码:

@Bean
protected ResourceServerConfigurerAdapter resourceServerConfigurerAdapter() {return new ResourceServerConfigurerAdapter() {...@Overridepublic void configure(ResourceServerSecurityConfigurer resources) throws Exception {resources.tokenExtractor(new TokenExtractor() {@Overridepublic Authentication extract(HttpServletRequest request) {String tokenValue = findCookie(ACCESS_TOKEN_COOKIE_NAME, request.getCookies());if (tokenValue == null) { return null; }return new PreAuthenticatedAuthenticationToken(tokenValue, "");}...});}};
}

这样做是从传入请求的Cookie列表中提取访问令牌(如果可以)。 然后,将自动完成解析和验证。 瞧!

建立基于角色的访问控制

在应用程序设置中,您定义打开哪些路径。 所有其他路径至少需要经过身份验证的会话。

这是OktaSpringSecurityRolesExampleApplication的另一个摘录:

@Bean
protected ResourceServerConfigurerAdapter resourceServerConfigurerAdapter() {return new ResourceServerConfigurerAdapter() {@Overridepublic void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/", "/login", "/images/**").permitAll().and().exceptionHandling().accessDeniedHandler(customAccessDeniedHandler);}...};
}

在这种情况下,您要告诉Spring Security允​​许任何未经身份验证的用户访问主页( / ),登录页面( /login )以及任何来自静态图像文件夹的内容。 这意味着默认情况下会自动限制所有其他路径。

此时,您还定义了一个自定义的访问拒绝处理程序。

@Controller
public class SecureController {@Autowiredprotected AppProperties appProperties;@RequestMapping("/authenticated")public String authenticated(Model model) {model.addAttribute("appProperties", appProperties);return "authenticated";}@RequestMapping("/users")@PreAuthorize("hasAuthority('users')")public String users() {return "roles";}@RequestMapping("/admins")@PreAuthorize("hasAuthority('admins')")public String admins() {return "roles";}@RequestMapping("/403")public String error403() {return "403";}
}

在此控制器中,我们定义了四个路径,所有这些路径都至少需要经过身份验证的用户。

真正的价值来自/users/admins路径。 请注意,它们都具有@PreAuthorize批注。 这意味着, 在随后的表达必须在方法之前应满足甚至会被输入。 hasAuthority函数确认经过身份验证的用户是否属于那些角色。 在此示例中,这些自动映射到我们之前创建的Okta组,这就是为什么在Okta的访问令牌中包含groups声明很重要的原因。

尽管这涉及到一些设置,但是现在您仅需一行代码即可实现基于角色的访问控制!

端到端配置

在客户端,我们从应用程序本身提供了一组Thymeleaf模板形式HTML页面。 因此,有一个单一的来源来提供客户端和服务器所需的配置值是有意义的。

使用Spring的@Component@ConfigurationProperties批注很容易。

这是AppProperties类:

@Component
@ConfigurationProperties("okta.oauth")
public class AppProperties {private String issuer;private String audience;private String clientId;private String rolesClaim;private String baseUrl;private String redirectUri;... getters and setters ...
}

@ConfigurationProperties告诉Spring从application.yml文件中okta.oauth属于okta.oauth密钥的所有属性。

@Component注释使Spring实例化此Object并使它可用于其他地方的自动装配。

看一下HomeController这段代码:

@Controller
public class HomeController {@Autowiredprotected AppProperties appProperties;...@RequestMapping("/login")public String login(Model model) {model.addAttribute("appProperties", appProperties);return "login";}
}

在单击/login端点时返回login视图之前,将AppProperties对象(在第4和5行自动AppProperties )添加到模型中。

这就是使它可用于Thymeleaf模板的原因:

<script th:inline="javascript">/*<![CDATA[*/$( document ).ready(function() {var data = {baseUrl: [[${appProperties.baseUrl}]],clientId: [[${appProperties.clientId}]],redirectUri: [[${appProperties.redirectUri}]],authParams: {issuer: [[${appProperties.issuer}]],responseType: ['token']}};window.oktaSignIn = new OktaSignIn(data);...});.../*]]>*/
</script>

开始编码!

就是这样! 试一试,让我知道它的进展! 我在Twitter上。

虽然我已经概述了将Okta的Groups机制与Spring Security的基于角色的访问控制结合使用的好处,但Okta的Java开发团队仍在努力开发我们的下一代SDK和集成。 请随时注意新的Okta Java Spring Boot Integration的即将发布的版本,该版本将支持其他OIDC工作流程,包括code以及托管的,可配置的登录和注册视图。

该帖子已从此处改编。

永不再构建身份验证 –喜欢构建用户管理? 使用Okta,您可以在几分钟内为您的应用程序添加社交登录,多因素身份验证和OpenID Connect支持。 立即创建一个免费的开发者帐户。

翻译自: https://www.javacodegeeks.com/2017/11/secure-java-app-spring-security-thymeleaf-okta.html

使用Spring Security,Thymeleaf和Okta保护Java应用程序的安全相关推荐

  1. 《深入理解 Spring Cloud 与微服务构建》第十八章 使用 Spring Security OAuth2 和 JWT 保护微服务系统

    <深入理解 Spring Cloud 与微服务构建>第十八章 使用 Spring Security OAuth2 和 JWT 保护微服务系统 文章目录 <深入理解 Spring Cl ...

  2. 使用Spring Security Oauth2 和 JWT保护微服务--Uaa授权服务器的编写

    学习自深入理解微服务 采用Spring Security OAuth2 和 JWT的方式,Uaa服务只需要验证一次,返回JWT.返回的JWT包含了用户的所有信息,包括权限信息 从三个方面讲解: JWT ...

  3. 一个具有Spring Boot,Spring Security和Stormpath的简单Web应用程序-15分钟

    建筑物身份管理,包括身份验证和授权? 尝试Stormpath! 我们的REST API和强大的Java SDK支持可以消除您的安全风险,并且可以在几分钟内实现. 注册 ,再也不会建立auth了! 更新 ...

  4. 使用 Acegi 保护 Java 应用程序

    第 1 部分: 架构概览和安全过滤器 Acegi Security System 是一种功能强大并易于使用的替代性方案,使您不必再为 Java 企业应用程序编写大量的安全代码.虽然它专门针对使用 Sp ...

  5. Spring Boot + Spring Security + Thymeleaf 举例

    本文以Spring Boot Thymeleaf为例,用Spring Security 保护 /admin 和 /user 页面 本例涉及的技术: 1. Spring Boot 1.5.6.REALE ...

  6. 使用Spring Security 资源服务器来保护Spring Cloud 微服务

    我在上一篇对资源服务器进行了简单的阐述,让大家对资源服务器的概念有了简单的认识,今天我将用实际例子来演示单体应用改造为Spring Cloud微服务时的资源服务器实现. 资源服务器改造 以Spring ...

  7. 使用Spring Security Oauth2 和 JWT保护微服务--资源服务器的编写

    编写hcnet-website的资源服务 依赖管理pom文件 hcnet-website工程的pom文件继承主maven的pom文件.在hcnet-website工程的pom文件中添加web功能的起步 ...

  8. spring security 3配置ACL时报java.lang.NoSuchMethodError: net.sf.ehcache.Cache.init

    严重: Exception sending context initialized event to listener instance of class org.springframework.we ...

  9. spring security+thymeleaf登录失败以及验证码错误提示

    直接上代码 @Component public class CustomAuthenticationFailureHandler implements AuthenticationFailureHan ...

最新文章

  1. (C++) CSP 201803-1 跳一跳
  2. instant.now时区不正确_Centos8如何更改时区
  3. JVM-09自动内存管理机制【内存分配和回收策略】
  4. python get请求 url传参_用Python-get方法向页面发起请求,参数传不进去是怎么回事...
  5. SpringBoot+SweeAlert实现alert提示与前后端数据交互
  6. Linux解决无法启动网络
  7. 【性能优化】 之性能视图及性能参数
  8. python 钉钉机器人发送图片_Python结合钉钉实时自动监控股票行情,上班炒股再也不怕老板发现...
  9. java arraylist枚举器遍历_Java基础(七)泛型数组列表ArrayList与枚举类Enum
  10. 【BZOJ 4671】异或图 【斯特林反演】【线性基】【贝尔数复杂度】
  11. Django-ORM数据库操作
  12. smarty 简单分页
  13. 在Blazor中构建数据库应用程序——第5部分——查看组件——UI中的CRUD列表操作
  14. 关于C#的sqlite数据库操作类
  15. Atitit 提升稳定性 错误处理 全局错误捕获 1.2. 可以uncaughtException来全局捕获未捕获的Error, 使用uncaughtException 2 1.2.1. 使用 t
  16. 他山之石——VBA SQL基础
  17. java中system.in怎么用
  18. Excel读写合集:Excel读写小白从不知所措到轻松上手
  19. Git 04 ---用Idea合并git分支
  20. Admin - 验证列表 ValidateList<E>

热门文章

  1. linux下离线安装gcc
  2. 21、mysql修改密码的方法总结
  3. SpringCloud Zuul(十)之配置路由prefix坑
  4. SpringBoot使用日志
  5. 分布式锁的多种实现方式
  6. 手把手教你搭建Maven项目
  7. 新闻发布项目——实体类(comment)
  8. java前台线程(普通线程) 和 后台线程
  9. MySQL 对于千万级的大表要怎么优化?
  10. aws ec2 选择可用区_AWS Messaging Services:选择合适的服务