使用Spring Security进行简单身份验证
朋友不允许朋友写用户身份验证。 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK。 在几分钟之内即可对任何应用程序中的用户进行身份验证,管理和保护。
身份验证对于除了最基本的Web应用程序之外的所有应用程序都至关重要。 谁在发出请求,需要数据或想要更新或删除数据? 您可以确定请求来自指定的用户或代理吗? 在当今的计算机安全环境中,很难确定地回答这个问题。 幸运的是,绝对没有理由重新发明轮子。
Spring Boot和Spring Security是Web应用程序开发的强大组合。 使用相对较少的代码行,您可以实现各种身份验证系统。 这些系统由专家根据规范进行测试,更新和实施。
在本教程中,您将构建一个非常简单的Spring Boot应用程序,该应用程序从basic-auth开始,并逐步进行基于表单的身份验证,基于表单的自定义身份验证以及使用Okta作为OAuth提供者的OAuth 2.0 / OpenID Connect。 我们还将介绍SAML身份验证。 但是,Spring Security SAML实现目前正在过渡中,尚未更新为最新版本的Spring Boot。
本教程专门研究身份验证,将授权保留另一天。 身份验证可以回答问题:谁在发出请求。 授权是在身份验证之后进行的,并回答以下问题:是否允许经过身份验证的用户发出特定请求?
使用Spring Security进行身份验证的要求和假设
本教程假定您对Java和Spring Boot基本熟悉。 该项目利用了Gradle构建系统(因为我发现Groovy DSL永远比XML更可取)。 但是,您不需要安装Gradle,因为所有项目都包括Gradle包装器。
您不需要全面了解OAuth 2.0和OpenID Connect(OIDC)–令人欣慰的是,由于OAuth 2.0和OpenID Connect有时非常复杂,详细且繁琐。 我仍在努力了解它的许多方面。 但是,基本的了解会有所帮助。 如果您想更进一步,本文结尾处的一些链接可以为您提供帮助。
非常(非常)简短地讲,OAuth 2.0是开放授权(开放授权)的第二个主要版本。 来自OAuth规范委员会的信息 :“ OAuth 2.0致力于简化客户端开发人员的工作,同时为Web应用程序,桌面应用程序,移动电话和客厅设备提供特定的授权流程。” 注意两件事:1)仅是授权,因此没有身份验证; 2)这是一个规范,因此没有实现。 OIDC建立在OAuth 2.0之上,以使用定义良好的令牌添加身份层(身份验证)。
Okta的Spring Security身份验证
Okta是一家身份访问和管理公司,提供大量的软件即服务身份产品。 我们具有OAuth 2.0和OpenID Connect的实现,该实现使向Spring Boot应用程序添加单点登录(SSO)变得容易。
我们的API使您能够:
- 验证和授权用户
- 存储有关您的用户的数据
- 执行基于密码的社交登录
- 通过多因素身份验证保护您的应用程序
- 以及更多! 查看我们的产品文档以获取更多信息
注册一个永久免费的开发者帐户 ,完成后,再回来学习更多关于使用Spring Boot和Spring Security构建身份验证的信息。
除此之外,您还需要一台计算机和一个Web浏览器。 如果没有这些,那么,你会在这里怎么样?
下载Spring Security示例应用程序
继续并从本教程的GitHub存储库下载示例应用程序。
git clone https://github.com/oktadeveloper/okta-spring-security-authentication-example.git
在项目中,您将看到三个目录:
basic-auth
form-auth
okta-oauth
通过Spring Security深入了解基本身份验证
到目前为止,基本身份验证是最简单的方法。 不幸的是,它是为在互联网上更简单的时间而设计的。 对于专业应用程序,它并不是真正起作用。 有时,当我需要一些简单而又快速的工具来使临时冲浪者脱离页面时,我便将其用于内部工具。 但是,基本身份验证在HTTP身份验证标头中以基本纯文本格式(base64编码)向用户发送凭据。 因此,基本身份验证应始终与SSL结合使用以保护用户凭据。 基本身份验证还使用浏览器生成的弹出面板来检索用户凭据。 面板不能设置样式或自定义。
首先,看一下build.gradle
文件。
plugins { id 'org.springframework.boot' version '2.1.5.RELEASE' id 'java'
} apply plugin: 'io.spring.dependency-management' group = 'com.okta.springsecurityauth'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8' repositories { mavenCentral()
} dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test'
}
此行设置Spring Boot版本:
id 'org.springframework.boot' version '2.1.5.RELEASE'
这是包括Spring Security和Spring MVC的两个依赖项。
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
其余的几乎都是样板。
这是主应用程序文件( src/main/java/com/okta/springsecurityauth/Application.java
)。
package com.okta.springsecurityauth; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }
}
这是Java应用程序的入口点。 要注意的主要事情是数量很少。 @SpringBootApplication
注释告诉Spring引导所有Spring Boot优点。
接下来看一下WebController, src/main/java/com/okta/springsecurityauth/WebController.java
。
package com.okta.springsecurityauth; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; @Controller
public class WebController { @RequestMapping("/")@ResponseBodypublic String index() {return "Welcome home!";}
}
Web控制器文件还有更多操作。 这是定义项目的唯一HTTP端点的地方。 该文件定义了一个简单的home控制器,该控制器返回文本字符串。
@Controller
批注告诉Spring该文件正在定义Web控制器端点。 @RequestMapping
批注定义HTTP请求和控制器方法之间的映射。 @ResponseBody
注释告诉Spring该方法将直接以String的形式返回请求主体,而不是返回模板文件的名称。
最后一个文件是定义所有安全性的位置。 巧妙地将其命名为SecurityConfiguration.java
。
看看src/main/java/com/okta/springsecurityauth/SecurityConfiguration.java
package com.okta.springsecurityauth; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user") .password("{noop}pass") // Spring Security 5 requires specifying the password storage format .roles("USER"); } }
您会看到需要很少的配置。 在第一种方法中,将fluent API与HttpSecurity
对象一起使用以配置Spring Security:激活安全性,对所有请求进行身份验证,并使用HTTP basic。
第二种方法实际上只是本教程的一点技巧。 它配置内存中的身份验证管理器,并创建一个凭据为user:pass
。
试一试吧! 在终端上,转到项目的根目录。
使用以下项目运行项目: ./gradlew bootRun
。
导航到http://localhost:8080
。
您将看到浏览器生成的登录表单。 输入凭证user
并pass
。 您会看到一个成功的页面,上面写着“欢迎回家!”
使用Spring Security升级到基于表单的身份验证
HTTP Basic身份验证非常简单,实际上在现实世界中并没有那么有用。 基于表单的身份验证要现实得多。 在您的IDE中打开/form-auth
文件夹。
build.gradle
文件是相同的。 Application.java
和WebController.java
文件也是如此。 唯一的重大更改是在SecurityConfiguration.java
文件中(并且在此文件中,仅一行已更改)。
src/main/java/com/okta/springsecurityauth/SecurityConfiguration.java
:
package com.okta.springsecurityauth; ... @Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin(); //See how ridiculously simple Spring is making things for us. All you had to do was change the httpBasic()
fluent method to formLogin()
and Spring Boot automatically generates a login form for you.
Run it using ./gradlew bootRun
.
You’ll see the auto-generated Spring Boot login form.
但是,如果您想样式化自己的自定义表单而不是使用Spring生成的表单,该怎么办? 没有太多的工作了。 首先,将Thymeleaf依赖项添加到build.gradle
文件中:
dependencies { ...implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' ... }
使用两个新的控制器方法更新WebController.java
文件:
package com.okta.springsecurityauth; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class WebController { @RequestMapping("/") @ResponseBody public String index() { return "You made it!"; } @RequestMapping("/login.html") public String login() { return "login.html"; } @RequestMapping("/login-error.html") public String loginError(Model model) { model.addAttribute("loginError", true); return "login.html"; } }
请注意,//login-error.html
路径使用与/login.html
路径相同的模板,但向Model
添加了loginError
属性。 这只是处理错误的一种方式。 另外,请注意,新的控制器方法没有@ResponseBody
批注。 这与新的Thymeleaf依赖性相结合,意味着这些方法将返回要呈现的模板的名称(与原始响应相反)。 默认情况下,假定模板位于src/main/resources/templates
文件夹中。 添加一个新文件:src/main/resources/templates/login.html
:
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Login page</title> <style> #container { padding-top:50px; width:400px; margin: 0 auto; font-size:1.5rem; } input { width: 100%; display:block; padding: 5px; font-size: 1.1rem; box-sizing: border-box; } label { margin-top:10px; display:block; } #submit, #submit:focus { margin-top: 20px; border-radius: 8px; padding: 10px; color: white; background-color: #2084ba; border: none; } .error { color: white; background-color: indianred; opacity: 0.7; padding: 10px; width: 100%; text-align: center; box-sizing: border-box; border-radius: 8px; } </style> </head> <body> <div id="container"> <h2>Login page</h2> <form th:action="@{/login.html}" method="post"> <label for="username">User</label> <input type="text" id="username" name="username" autofocus="autofocus" /> <label for="password">Pass</label> <input type="password" id="password" name="password" /> <input id="submit" type="submit" value="Log in" /> </form> <p th:if="${loginError}" class="error">There was a problem logging you in</p> </div> </body> </html>
这是用于登录页面的Thymeleaf模板文件。 Thymeleaf是与Spring Boot一起使用的标准模板系统。 这是一个功能齐全的模板系统,具有大量功能。 查看项目网站以获取更多信息。 您需要做的最后更改是更新SecurityController.java
文件中的configure(HttpSecurity http)
方法:
package com.okta.springsecurityauth; ... @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login.html") .failureUrl("/login-error.html") .permitAll(); } ... }
添加了以下三行:
.loginPage("/login.html") .failureUrl("/login-error.html") .permitAll();
它们定义了自定义登录端点,登录错误端点,并指示Spring Security允许对这些端点的所有请求。 使用./gradlew bootRun
再次运行该应用程序。 这次,您将看到自定义登录表单。
(几乎)是SAML时间!
Spring Security SAML扩展目前正在不断变化。 有一些非官方的2.x发行版可以运行,但是没有得到官方的支持。 从Spring Security SAML GitHub页面 :
该项目正在被重写。 有一个在一个基实现发展 ,包括在里程碑版本里程碑库。
在development-3.0分支中,我们正在创建一个在里程碑之上构建的解决方案,并与Spring Security更好地保持一致。 该分支的目的是将其与Spring Security项目合并,并作为Spring Security核心的一部分发布。
因此,我们将不会发布2.0.0里程碑的任何正式版本,但将对其进行维护,直到该里程碑中存在的所有功能都属于Spring Security。
如果您想冒险进入Spring Boot SAML的当前状态, Spring SAML Extension Docs是一个不错的起点。 Okta的Matt Raible也提供了一个很棒的教程 ,说明如何使用Spring Boot 1.x实现SAML。 Vincenzo De Notari提供了一个使用SAML 2.0和Spring Boot 2.1.3 的示例服务提供程序实现 。 注意:如果要使用Okta测试SAML,则需要请求Okta企业版试用。
添加OAuth 2.0 + OpenID Connect身份验证
进入developer.okta.com仪表板后,创建一个OIDC应用程序:
- 在顶部菜单中,单击“ 应用程序”
翻译自: https://www.javacodegeeks.com/2019/07/simple-authentication-spring-security.html
使用Spring Security进行简单身份验证相关推荐
- 使用Spring Security添加RememberMe身份验证
我在" 将社交登录添加到Jiwhiz博客"中提到,RememberMe功能不适用于Spring Social Security. 好吧,这是因为该应用程序现在不通过用户名和密码对用 ...
- 如何使用Spring Security和Basic身份验证保护Jersey REST服务
在我之前的博客文章" 检查REST API是否有效的快速方法–从清单文件中获取GET详细信息"中 ,我展示了如何开发REST资源以轻松检查开发的REST API是否可用. 在本文中 ...
- java登录密码验证失败_java – Spring Security:如果身份验证失败,则重定向到登录页面...
我们有两种登录方式. >用户名和密码由请求标头中的其他应用程序发送.检查IT,如果用户名和密码正确,则进入.[为此编写自定义过滤器] >如果请求标头中不存在用户名和密码,则会显示登录屏幕. ...
- java token身份认证_java – 基于Spring Security Token的身份验证
以下是我能够实现基于令牌的身份验证和基本身份验证的方法 SpringSecurityConfig.java @Configuration @EnableWebSecurity public class ...
- Spring Boot+Spring Security+JWT 实现token验证
Spring Boot+Spring Security+JWT 实现token验证 什么是JWT? JWT的工作流程 JWT的主要应用场景 JWT的结构 SpringBoot+Spring Secur ...
- 使用Spring Security进行自动登录验证
** 原文来自师兄的博客 **: http://blog.csdn.net/df19900725/article/details/78085152 http://www.datalearner.com ...
- Spring Security with Spring Boot 2.0:使用Servlet堆栈的简单身份验证
Spring安全性是一个很好的框架,可节省开发人员的大量时间和精力. 此外,它还具有足够的灵活性,可以自定义并满足您的需求. 随着spring的发展,spring安全性也使得在项目中设置安全性变得更加 ...
- 使用React,Spring Boot和用户身份验证构建CRUD应用程序
建筑物身份管理,包括身份验证和授权? 尝试Stormpath! 我们的REST API和强大的Java SDK支持可以消除您的安全风险,并且可以在几分钟内实现. 注册 ,再也不会建立auth了! Re ...
- Spring Security实现用户名密码验证的原理
title: Spring Security date: 2019-08-05 16:40:27 categories: 后端 tags: 后端 权限管理 Spring Security Spring ...
最新文章
- 2019 半导体领袖新年展望(一)| 半导体行业观察
- ELK 经典用法—企业自定义日志收集切割和mysql模块
- Javascript的继承
- iphone如何查看wifi密码_怎么在手机和电脑查看已连接的wifi密码
- aliyun gradle 代理_gradle|gradle 配置阿里云镜像和插件镜像
- java was datasource_mybatis默认的数据源连接池(PooledDataSource和UnPooledDataSource)
- GitHub 热点速览:不可思议的浏览器 Browser-2020 周涨 Star 超 3 千
- 自实现进程管理器linux,【Linux工具篇】supervisor进程管理器
- Spring容器和Spring应用上下文的理解
- 【生信进阶练习1000days】day2-学习summarized experimental data与Down stream analysis
- java 日期格式化工具类
- LM1875功放板设计实例
- 八大地图API开发平台大比拼
- 强化学习——Modle-free DRL算法
- linux c设置打印机属性,如何恢复打印机属性的“功能”部分
- 【LAB4-Cisco】OSPF邻居建立过程与LSDB分析
- OSPF学习小结与实验
- Nginx 实现文件夹上传(保留目录结构)
- CFE的刷写与修改教程
- Android下拉列表框