其他

使用 Keyclock 轻松保护 Spring Boot 应用程序

2017-06-29 OSC-协作翻译 开源中国


尽管安全性是应用程序的一个关键点,但是在开发中实施起来确实比较麻烦。更加麻烦的是,这个关键点通常不怎么受重视,实现的效果普遍的 low,而且受到诸多方面的掣肘。而最近安全服务器的出现,就可以将认证和授权方面的业务逻辑外包和分派出去。在这些服务器中,最有希望的是 Keycloak,因为它开放源代码,灵活,而且未来能适合任何技术亦未可知,它也可以轻松地部署并适应于其自身的基础设施之中。

另外,Keycloak 也不仅仅是一个身份验证服务器,它还提供了完整的身份管理系统,可以实现诸如 LDAP 那样的第三方的用户联盟。可以看看这里

该项目可以在GitHub上找到。


Spring Boot 和 Keycloak


Keycloak 为需要与 Keycloak 实例交互的应用程序提供适配器。 有用于 WildFly / EAP,NodeJS,JavaScript 的适配器,当然也有用于 Spring Boot 的适配器。

设置 Keycloak 服务

你有多个选项来设置一个 Keycloak 服务器,但最简单的一个可能是获取一个独立的发布。解压缩,瞧着! 打开一个终端,然后切换到你解压缩的 Keycloak 服务,并从 bin 目录下运行:

然后打开浏览器,然后转到进入 http://localhost:8080/auth。

由于这是服务的第一次运行,你必须创建一个管理员账户才行,所以让来我们创建一个管理员用户,用户名为 admin,密码为 admin:

现在您可以登录到管理控制台并开始配置 Keycloak。

创建一个新的 Realm

Keycloak 定义了一个 realm 的概念,并且你将在 realm 中定义客户端,在 Keycloak 中的术语是指由 Keycloak 保护的应用程序。 它可以是 Web App,Java EE 后端,Spring Boot 等等。

所以让我们创建一个新的 realm,只需点击“添加领域”按钮:

让我们称之为“SpringBoot.”

创建客户端,角色以及用户

现在我们需要定义一个客户端,这就会是我们的 Spring Boot 应用程序。转到“Clients”部分,然后单击“Create”按钮。我们把这个客户端叫做“product-app”:

在接下来的界面上,我们可以让大部分东西都保留默认设置,只需要输入一个有效的重定向 URL,让 Keycloak 将其用于用户进行了身份验证之后。这里我们输入这个 URL:“http:// localhost:8081 / *”。

不要忘了把这些配置保存下来哦!

现在,我们要把需要分配给用户的角色定义好。创建一个名为“user”的简单角色:

最后,我们得创建一个用户。这里只需要用户名属性就可以了,这里我们就叫他“testuser”吧:

最后,我们需要设置一下凭据,所以要转到用户的“Credencials(凭据)”选项卡界面,并选择一个密码。我会在本文的余下部分使用“password”,还得确保把“Temporary(临时)”这个标志关闭了,除非你是想要用户可以在首次认证时更改密码。

现在转到“Role Mappings(角色映射)”选项卡界面来分配“user”这个角色:

现在我们就完成了 Keycloak 服务器的配置,可以开始构建 Spring Boot App 了!


创建一个简单的 App


让我们来创建一个简单的 Spring Boot App。你也许会想要使用 Spring Initializrr,这时候要把如下选项给选上:

  • Web

  • Freemarker

  • Keycloak

将你的 App 命名为“product-app”,然后把生成的工程下载下来:

将应用程序导入你喜欢使用的 IDE 里面,这里我会使用 IntelliJ。

我们的应用程序会比较简单,只包含两个页面:

  • 一个 index.html,它将是登录页面,里面只包含产品页面的链接。

  • Products.ftl,它将是我们的产品页面的模板,只能被通过了身份验证的用户访问到。

首先我们在“/src/resources/static”目录中创建一个简单的 index.html 文件:

现在,我们需要一个控制器:

你会发现这很简单,就是定义了产品页面的映射,然后再为注销操作定义一个映射。你还会注意到,我们调用了一个“ProductService”,它会返回一个字符串列表,我们把这个列表放到 Spring MVC Model 对象里面去,所以我们要创建这个服务:

我们还需要创建 product.ftl 模板。要在“src/resources/templates”中创建此文件:

在这里,我们简单地遍历了 Spring MVC Model 对象中的产品列表,并添加一个从我们的应用程序中注销的链接。

我们要做的就是向 application.properties 中添加一些 keycloak 相关的属性。

定义 Keycloak 的配置

一些属性是必须要有的:

我们需要定义一些安全方面的约束,就像你在 web.xml 中使用 Java EE 应用的时候要进行的配置一样:

在这里,我们简单地定义每个向 /products/* 发起的请求都应该通过用户验证,而且该用户得有“user”这个角色。

现在,我们只需要配置最后一个属性来确保我们的应用程序将会在端口8081上运行:

这样我们就都设置好了,可以把应用程序运行起来了!

要运行这个 Spring Boot 应用程序,有很多方式可以选择。使用 Maven 的话,你可以简单地像下面这样做就行了:

现在导航到“http//localhost8080”,你应该就可以看到登录页面你了。点击“products”链接,会被重定向到 Keycloak 登录页面:

使用我们的用户“testuser/password”进行登录,应该会重定向到产品页面:

恭喜哦!现在你已经使用 Keycloak 为你的第一个 Spring Boot 应用程序加上了防护措施。现在注销并返回到 Keycloak 管理员控制台,你就会知道如何去“调整”登录页面。例如,您可以启用“Remember Me(记住我)”和“User Registration(用户注册)”功能。为此,请点击保存按钮并返回到登录界面。在那里你会这些功能已经添加上了。


引入 Spring Security 支持


如果你是 Spring 用户而且一直在玩安全方面的东西的话,那么很有可能就会要用到 Spring Security。而我这里有一个好消息:我们还有一个 Keycloak Spring Security Adapter,而且它已经被包含在我们的 Spring Boot Keycloak Starter 中了。

我们来看看如何将 Spring Security 和 Keycloak 放到一起使用。

添加 Spring Security Starter

首先,我们需要 Spring Security 的库。最容易的方法就是将 spring-boot-starter-security  的 artifact 添加到你的 pom.xml 中:

创建一个 SecurityConfig 类

同其它的得到 Spring Security 防护的应用程序一样, 这里也需要一个扩展自 WebSecurityConfigurerAdapter 的配置类。Keycloak 提供了它自己的一个子类来给你进行再次继承:

让我们来仔细看看最重要的几个方法:

  • configureGlobal: 这里我们修改 Granted Authority Mapper。在 Spring Security 中角色都默认带上了前缀 ROLE_。我们可以在我们的 Realm 配置中把这个改掉,不过这样做会让其它不知道这个约定的应用程序感到困惑, 所以这里我们分配了一个 SimpleAuthorityMapper 来确保不会有前缀被加上去。

  • keycloakConfigResolver: Keycloak Spring Security Adapter 默认会从你的 classpath 中找一个叫做 keycloak.json 的文件。不过这里我们并不像要利用上 Spring Boot 的属性文件支持。

  • configure: 这就是我们定义安全限制的地方。这个相当容易理解。我们要做的就是把带有“user” 角色的路径 “/products” 给保护起来。

现在我们可以在我们的 application.properties 文件中将之前已经定义的安全限制给去掉了,然后添加另外一个属性来将我们的 KeyCloak 用户名映射到 Principal 名称上去:

现在我们设置可以将规则诸如到我们的控制器方法中去,并且将用户名放到 Spring 的 MVC model 中:

最后,我们可以更新 product.ftl 模板,来把用户名打印出来:

再一次重启你的 App,可以看到它仍然可以运行起来,你也应该能看到你的用户打印在了产品页面之上:

总结


我们在本文中了解了如何部署和配置一个 Keycloak 服务端然后用它来为 Spring Boot 应用添加防护, 首先是通过使用 Java EE 安全约束,然后是通过集成 Spring Security。在接下来的文章中,我们将会对这个单一的应用程序进行分解,藉此机会来:

  • 看看如何来保护一个微服务。

  • 看看微服务是如何保护每一次“会话”的。

  • 看看用 AngularJS 构建的一个 Pure Web App 是如何用 Keycloak 防护起来,还有如何调用被防护的微服务的。

截屏

本文有“截屏”格式:

  • https://developers.redhat.com/video/youtube/vpgRTPFDHAw/ (Part 1)

  • https://developers.redhat.com/video/youtube/O5ePCWON08Y/ (Part 2)

资源

  • Github 工程

  • Keycloak 网站

  • Spring Boot Keycloak Adapter 文档

  • Spring Security Keycloak Adapter 文档

  • Spring Initializr 站点



推荐阅读

如此“封闭”的腾讯,这些年都开源了哪些项目?

7 款顶级的开源 Web 分析软件推荐

全栈开发——动手打造属于自己的直播间

关于 ASP.NET 内存缓存你需要知道的 10 点

点击“阅读原文”查看更多精彩内容

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存