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

永不再构建身份验证 –喜欢构建用户管理? 使用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/348353.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

红旗linux添加usb无线网卡,在Ubuntu 8.10中安装无线网卡RTL8187SE驱动

本人的笔记本是微星的Wind U90&#xff0c;自带的无线网卡是RTL8187SE。这款无线网卡在一般的Linux下是没有驱动的&#xff0c;微星的官方也仅仅提供在OpenSUSE下的驱动。为了在我的Ubuntu下使用这个网卡&#xff0c;只能自己动手了。还好&#xff0c;有了互联网上各位大侠和微…

将Google reCaptcha与Spring Boot应用程序结合使用

介绍 Google的reCaptcha是一个用于防止漫游器向您的公共表单提交数据或访问您的公共数据的库。 在本文中&#xff0c;我们将研究如何将reCaptcha与基于Spring Boot的Web应用程序集成 设置验证码 您应该从管理面板创建API密钥。 您必须创建一个示例应用程序&#xff0c;如下所…

探索 HTTP 请求的世界:get 和 post 的奥秘(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

linux 书签管理工具,在书签管理工具中使用Ubuntu字体

通过便捷书签管理程序(Bookmarklet&#xff0c;一种在浏览器中存放书签URL地址的应用程序)来在大多数的网站上推广使用Ubuntu系统的默认字体。——读者米格尔费尔南迪斯米格尔在他的想法产生之前告诉我们说&#xff1a;“我发现Ubuntu系统的字体在提高可读性上超过了绝大多数的…

linux18.2安装界面,Ubuntu 18.10下安装Grub Customizer 5.1.0配置grub2图形化界面

配置Grub2/burg引导装载程序Grub Customizer 5.1.0新增加对Ubuntu 18.10的支持&#xff0c;我们可以用PPA源来安装&#xff0c;同时还支持Ubuntu 18.04、16.04、14.04。Grub Customizer简介Grub Customizer是用来配置Grub/burg引导装载程序的图形工具&#xff0c;此次发布的5.1…

使用Eclipse和Open Liberty的Java EE 8上的Java 9

几周前&#xff0c;我写了一篇文章&#xff0c;标题为哪个IDE和服务器支持Java EE 8和Java9 &#xff0c;着眼于Java 9和Java EE 8之间的当前运行状态。您可以期待事情发展很快&#xff0c;我们现在有了一些alpha和支持Java 9和Java EE 8的开发版本。这些是– Payara 5 –适用…

Java命令行界面(第28部分):getopt4j

getopt4j的页面将其描述为“一个根据GNU样式解析命令行参数的库。” 然后&#xff0c; 页面介绍getopt4j &#xff1a;“getopt4j库旨在以与glibc &#xff08;GNU C运行时库&#xff09;中的C getopt&#xff08;&#xff09;函数相同的方式解析命令行选项。 与原始产品相比&a…

新版ipados可以编辑C语言吗,iPadOS新增了五个有用的功能,看你需不需要

主屏幕上的可自定义小部件苹果通过“ iOS 14”对“小工具”进行了大修&#xff0c;引入了新的设计&#xff0c;功能和自定义选项。这些“小部件”也出现在在iPhone上&#xff0c;您可以抓住任何小部件并将其添加到应用程序图标旁边的“主屏幕”中&#xff0c;但是不能在“ iPad…

c 语言已知两点求第三点,已知3点座标,求第一点到第二点和第三点构成的直线的距离。...

已知3点座标&#xff0c;求第一点到第二点和第三点构成的直线的距离。以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;已知3点座标&#xff0c;求第一点到第二点和第三点构成的直线的距离。解…

android 组合属性动画,Android属性动画组合(sequence串行、together并行)

在android中用原生api实现一系列复杂动画会很麻烦&#xff0c;所以对属性动画进行了一定封装&#xff0c;让使用起来更简单&#xff0c;能够按照人的思维依次编写动画。简单效果&#xff1a;使用方法&#xff1a;添加依赖&#xff1a;dependencies { compile"com.steven:A…

jta atomikos_带有Atomikos示例的Tomcat中的Spring JTA多个资源事务

jta atomikos在本教程中&#xff0c;我们将向您展示如何使用Atomikos Transaction Manager在Tomcat服务器中实现JTA多个资源事务。 Atomicos事务管理器为分布式事务提供支持。 这些是多阶段事务&#xff0c;通常使用多个数据库&#xff0c;必须以协调的方式提交。 分布式事务由…

台电+android+电话,通话系统_台电 G17s_平板电脑评测-中关村在线

通话系统将两张联通3G的SIM卡插入台电G17s之后&#xff0c;我们来感受一下它通话系统的使用是否令人满意。和一般的双卡Android手机平板一样&#xff0c;该机也不支持热插拔&#xff0c;需要将机器彻底关闭后插入SIM卡再开机。并且在开机后屏幕会弹出SIM卡信息&#xff0c;并询…

功能Java示例 第2部分–讲故事

这是称为“ Functional Java by Example”的系列文章的第2部分。 我在本系列的每个部分中发展的示例是某种“提要处理程序”&#xff0c;用于处理文档。 在上一部分中&#xff0c;我从一些原始代码开始&#xff0c;并应用了一些重构来描述“什么”而不是“如何”。 为了帮助代…

OpenHub框架–下一个有趣的功能

这是有关OpenHub框架的系列文章中的第三篇&#xff0c;第一篇介绍OpenHub框架 &#xff0c;第二篇介绍异步消息传递模型 。 该系列的最后一篇文章将更详细地介绍其他一些有趣的功能&#xff0c;并说明为什么OpenHub可以成为您的集成项目的理想选择的原因。 节流 节流是一种功…

ubuntu生成密钥和证书_基于浏览器的密钥生成以及与浏览器的密钥/证书存储的交互...

ubuntu生成密钥和证书想象以下情况&#xff1a; 您需要从访问您的网站的用户那里获取一个密钥&#xff08;在非对称情况下为用户的公共密钥 &#xff09;&#xff0c;并希望浏览器记住私有部分&#xff0c;而不会因冗长的导入过程而困扰用户。 老实说&#xff0c;实际上&#…

android数据流分类,【Android工程之类】1 MVVM架构 - MVVM与单向数据流

前言这个系列将讲述使用MVVM架构、LiveData、Room、Kodein、Retrofit、EventBus来建立一个统一的、优雅的、可维护的TODO程序&#xff0c;本系列分为多个章节&#xff0c;从0开始一步一步引入这些优秀的库。下图展示的是Jetpack组件库包含的内容&#xff0c;这套的架构方案的核…

java ssl证书_Java安全教程–创建SSL连接和证书的分步指南

java ssl证书在有关应用JEE安全性的系列文章中&#xff0c;我们为您提供了另一个有关如何在Java EE应用程序中创建SSL连接和创建证书的详细教程。 如我们之前的文章中所述&#xff0c; 安全套接字层&#xff08;SSL&#xff09;/传输层安全性&#xff08;TLS&#xff09;将启用…

通过Okta的单点登录保护Spring Boot Web App的安全

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕&#xff1f; 尝试使用Okta API进行托管身份验证&#xff0c;授权和多因素身份验证。 您可以使用SpringBoot和Okta在不到20分钟的时间内启动具有完整用户身份和授权管理的企…

java ee cdi_Java EE CDI程序化依赖关系消歧示例–注入点检查

java ee cdi在本教程中&#xff0c;我们将看到在注入Java EE CDI bean时如何避免程序依赖消除歧义。 我们已经在Jave EE依赖关系消除歧义示例中展示了如何避免CDI Bean中的依赖关系歧义消除。 在这里&#xff0c;我们将向您展示如何以动态方式避免依赖消除歧义。 我们将通过检查…

atom自动补全html代码,Atom - Emmet插件的使用详解(HTML/CSS代码自动补全)

一、Emmet的安装与介绍Emmet (前身为 Zen Coding) 是一个能大幅度提高前端开发效率的工具&#xff0c;能够实现 HTML、CSS 的快速编写。官网地址&#xff1a;http://emmet.io/官方文档&#xff1a;http://docs.emmet.io/cheat-sheet/Atom的emmet介绍页面&#xff1a;https://at…