博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Security示例教程
阅读量:2531 次
发布时间:2019-05-11

本文共 15926 字,大约阅读时间需要 53 分钟。

Spring Security provides ways to perform authentication and authorization in a web application. We can use spring security in any servlet based web application.

Spring Security提供了在Web应用程序中执行身份验证和授权的方法。 我们可以在任何基于servlet的Web应用程序中使用spring security。

Spring安全 (Spring Security)

Some of the benefits of using Spring Security are:

使用Spring Security的一些好处是:

  1. Proven technology, it’s better to use this than reinvent the wheel. Security is something where we need to take extra care, otherwise our application will be vulnerable for attackers.

    经过验证的技术,比重新发明轮子更好。 安全是我们需要格外小心的地方,否则我们的应用程序将容易受到攻击者的攻击。
  2. Prevents some of the common attacks such as CSRF, session fixation attacks.

    防止某些常见的攻击,例如CSRF,会话固定攻击。
  3. Easy to integrate in any web application. We don’t need to modify web application configurations, spring automatically injects security filters to the web application.

    易于集成到任何Web应用程序中。 我们不需要修改Web应用程序配置,spring会自动将安全过滤器注入Web应用程序。
  4. Provides support for authentication by different ways – in-memory, DAO, JDBC, LDAP and many more.

    通过不同的方式提供对身份验证的支持-内存,DAO,JDBC,LDAP等。
  5. Provides option to ignore specific URL patterns, good for serving static HTML, image files.

    提供忽略特定URL模式的选项,非常适合提供静态HTML,图像文件。
  6. Support for groups and roles.

    支持组和角色。

Spring安全示例 (Spring Security Example)

We will create a web application and integrate it with Spring Security.

我们将创建一个Web应用程序并将其与Spring Security集成。

Create a web application using “Dynamic Web Project” option in Eclipse, so that our skeleton web application is ready. Make sure to convert it to maven project because we are using Maven for build and deployment. If you are unfamiliar with these steps, please refer .

使用Eclipse中的“ Dynamic Web Project ”选项创建一个Web应用程序,以便准备好我们的框架Web应用程序。 确保将其转换为Maven项目,因为我们使用Maven进行构建和部署。 如果您不熟悉这些步骤,请参考 。

Once we will have our application secured, final project structure will look like below image.

一旦我们确保了应用程序的安全,最终的项目结构将如下图所示。

We will look into three spring security authentication methods.

我们将研究三种Spring安全认证方法。

  1. in-memory

    在记忆中
  2. DAO

  3. JDBC

    JDBC

For JDBC, I am using MySQL database and have following script executed to create the user details tables.

对于JDBC,我正在使用MySQL数据库,并已执行以下脚本来创建用户详细信息表。

CREATE TABLE `Employees` (  `username` varchar(20) NOT NULL DEFAULT '',  `password` varchar(20) NOT NULL DEFAULT '',  `enabled` tinyint(1) NOT NULL DEFAULT '1',  PRIMARY KEY (`username`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `Roles` (  `username` varchar(20) NOT NULL DEFAULT '',  `role` varchar(20) NOT NULL DEFAULT '',  PRIMARY KEY (`username`,`role`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `Employees` (`username`, `password`, `enabled`)VALUES	('pankaj', 'pankaj123', 1);INSERT INTO `Roles` (`username`, `role`)VALUES	('pankaj', 'Admin'),	('pankaj', 'CEO');commit;

We would also need to configure JDBC DataSource as JNDI in our servlet container, to learn about this please read .

我们还需要在servlet容器中将JDBC DataSource配置为JNDI,要了解此信息,请阅读 。

Spring Security Maven依赖关系 (Spring Security Maven Dependencies)

Here is our final pom.xml file.

这是我们最终的pom.xml文件。

4.0.0
WebappSpringSecurity
WebappSpringSecurity
0.0.1-SNAPSHOT
war
org.springframework.security
spring-security-web
3.2.3.RELEASE
org.springframework.security
spring-security-config
3.2.3.RELEASE
org.springframework.security
spring-security-taglibs
3.0.5.RELEASE
javax.servlet
jstl
1.2
compile
javax.servlet.jsp
jsp-api
2.1
provided
javax.servlet
javax.servlet-api
3.0.1
provided
commons-logging
commons-logging
1.1.1
org.springframework
spring-jdbc
4.0.2.RELEASE
src
maven-compiler-plugin
3.1
1.7
1.7
maven-war-plugin
2.3
WebContent
false

We have following dependencies related to Spring Framework.

我们有以下与Spring Framework相关的依赖项。

  1. spring-jdbc: This is used for JDBC operations by JDBC authentication method. It requires DataSource setup as JNDI. For complete example of it’s usage, please refer

    spring-jdbc :通过JDBC认证方法用于JDBC操作。 它要求将数据源设置为JNDI。 有关其用法的完整示例,请参考
  2. spring-security-taglibs: Spring Security tag library, I have used it to display user roles in the JSP page. Most of the times, you won’t need it though.

    spring-security-taglibs :Spring Security标记库,我已使用它在JSP页面中显示用户角色。 大多数时候,您虽然不需要它。
  3. spring-security-config: It is used for configuring the authentication providers, whether to use JDBC, DAO, LDAP etc.

    spring-security-config :用于配置身份验证提供程序,是否使用JDBC,DAO,LDAP等。
  4. spring-security-web: This component integrates the Spring Security to the Servlet API. We need it to plugin our security configuration in web application.

    spring-security-web :该组件将Spring Security集成到Servlet API。 我们需要它来将安全配置插入Web应用程序中。

Also note that we will be using Servlet API 3.0 feature to add listener and filters through programmatically, that’s why servlet api version in dependencies should be 3.0 or higher.

还要注意,我们将使用Servlet API 3.0功能以编程方式添加侦听器和过滤器,这就是为什么依赖项中的servlet API版本应为3.0或更高。

Spring Security示例视图页面 (Spring Security Example View Pages)

We have JSP and HTML pages in our application. We want to apply authentication in all the pages other than HTML pages.

我们的应用程序中包含JSP和HTML页面。 我们想在HTML页面以外的所有页面上应用身份验证。

health.html

health.html

Health Check

Service is up and running!!

index.jsp

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib uri="https://www.springframework.org/security/tags" prefix="sec" %>
Home Page

Home Page

Hello

Roles:

I have included index.jsp as welcome-file in the application deployment descriptor.

我已经将index.jsp作为welcome-file包含在应用程序部署描述符中。

Spring Security takes care of CSRF attack, so when we are submitting form for logout, we are sending the CSRF token back to server to delete it. The CSRF object set by Spring Security component is _csrf and we are using it’s property name and token value to pass along in the logout request.

Spring Security负责CSRF攻击,因此,当我们提交注销表单时,我们会将CSRF令牌发送回服务器以将其删除。 Spring Security组件设置的CSRF对象是_csrf ,我们正在使用它的属性名称和令牌值在注销请求中传递。

Let’s look at the Spring Security configurations now.

现在让我们看一下Spring Security的配置。

Spring Security示例UserDetailsS​​ervice DAO实现 (Spring Security Example UserDetailsService DAO Implementation)

Since we will be using DAO based authentication also, we need to implement UserDetailsService interface and provide the implementation for loadUserByUsername() method.

由于我们还将使用基于DAO的身份验证,因此我们需要实现UserDetailsService接口,并提供loadUserByUsername()方法的实现。

Ideally we should be using some resource to validate the user, but for simplicity I am just doing basic validation.

理想情况下,我们应该使用一些资源来验证用户,但是为了简单起见,我只是在进行基本验证。

AppUserDetailsServiceDAO.java

AppUserDetailsServiceDAO.java

package com.journaldev.webapp.spring.dao;import java.util.Collection;import java.util.List;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;public class AppUserDetailsServiceDAO implements UserDetailsService {	protected final Log logger = LogFactory.getLog(getClass());		@Override	public UserDetails loadUserByUsername(final String username)			throws UsernameNotFoundException {				logger.info("loadUserByUsername username="+username);				if(!username.equals("pankaj")){			throw new UsernameNotFoundException(username + " not found");		}				//creating dummy user details, should do JDBC operations		return new UserDetails() {						private static final long serialVersionUID = 2059202961588104658L;			@Override			public boolean isEnabled() {				return true;			}						@Override			public boolean isCredentialsNonExpired() {				return true;			}						@Override			public boolean isAccountNonLocked() {				return true;			}						@Override			public boolean isAccountNonExpired() {				return true;			}						@Override			public String getUsername() {				return username;			}						@Override			public String getPassword() {				return "pankaj123";			}						@Override			public Collection
getAuthorities() { List
auths = new java.util.ArrayList
(); auths.add(new SimpleGrantedAuthority("admin")); return auths; } }; }}

Notice that I am creating anonymous inner class of UserDetails and returning it. You can create an implementation class for it and then instantiate and return it. Usually that is the way to go in actual applications.

注意,我正在创建UserDetails匿名内部类并返回它。 您可以为其创建一个实现类,然后实例化并返回它。 通常,这是实际应用中的方法。

Spring Security示例WebSecurityConfigurer实现 (Spring Security Example WebSecurityConfigurer implementation)

We can implement WebSecurityConfigurer interface or we can extend the base implementation class WebSecurityConfigurerAdapter and override the methods.

我们可以实现WebSecurityConfigurer接口,也可以扩展基本实现类WebSecurityConfigurerAdapter并覆盖方法。

SecurityConfig.java

SecurityConfig.java

package com.journaldev.webapp.spring.security;import javax.naming.Context;import javax.naming.InitialContext;import javax.sql.DataSource;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.WebSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import com.journaldev.webapp.spring.dao.AppUserDetailsServiceDAO;@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {	@Override	public void configure(AuthenticationManagerBuilder auth)			throws Exception {		// in-memory authentication		// auth.inMemoryAuthentication().withUser("pankaj").password("pankaj123").roles("USER");		// using custom UserDetailsService DAO		// auth.userDetailsService(new AppUserDetailsServiceDAO());		// using JDBC		Context ctx = new InitialContext();		DataSource ds = (DataSource) ctx				.lookup("java:/comp/env/jdbc/MyLocalDB");		final String findUserQuery = "select username,password,enabled "				+ "from Employees " + "where username = ?";		final String findRoles = "select username,role " + "from Roles "				+ "where username = ?";				auth.jdbcAuthentication().dataSource(ds)				.usersByUsernameQuery(findUserQuery)				.authoritiesByUsernameQuery(findRoles);	}		@Override    public void configure(WebSecurity web) throws Exception {        web            .ignoring()                // Spring Security should completely ignore URLs ending with .html                .antMatchers("/*.html");    }}

Notice that we are ignoring all HTML files by overriding configure(WebSecurity web) method.

注意,我们将通过覆盖configure(WebSecurity web)方法来忽略所有HTML文件。

The code shows how to plugin JDBC authentication. We need to configure it by providing DataSource. Since we are using custom tables, we are also required to provide the select queries to get the user details and it’s roles.

该代码显示了如何插入JDBC身份验证。 我们需要通过提供DataSource对其进行配置。 由于我们使用的是自定义表,因此还需要提供选择查询以获取用户详细信息及其角色。

Configuring in-memory and DAO based authentication is easy, they are commented in above code. You can uncomment them to use them, make sure to have only one configuration at a time.

在上面的代码中注释了配置基于内存和DAO的身份验证很容易。 您可以取消注释它们以使用它们,请确保一次只有一个配置。

@Configuration and @EnableWebSecurity annotations are required, so that spring framework know that this class will be used for spring security configuration.

@Configuration@EnableWebSecurity注释是必需的,因此spring框架知道该类将用于spring安全配置。

Spring Security Configuration is using and based on the authenticate method, some of the methods won’t be available later on. For example, auth.userDetailsService() returns the instance of UserDetailsService and then we can’t have any other options, such as we can’t set DataSource after it.

Spring Security Configuration使用的是并且基于authenticate方法,某些方法稍后将不可用。 例如, auth.userDetailsService()返回UserDetailsService的实例,然后我们将没有其他任何选项,例如不能在其后设置DataSource。

将Spring Security Web与Servlet API集成 (Integrating Spring Security Web with Servlet API)

The last part is to integrate our Spring Security configuration class to the Servlet API. This can be done easily by extending AbstractSecurityWebApplicationInitializer class and passing the Security configuration class in the super class constructor.

最后一部分是将我们的Spring Security配置类集成到Servlet API。 这可以通过扩展AbstractSecurityWebApplicationInitializer类并在超类构造函数中传递Security配置类来轻松完成。

SecurityWebApplicationInitializer.java

SecurityWebApplicationInitializer.java

package com.journaldev.webapp.spring.security;import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;public class SecurityWebApplicationInitializer extends		AbstractSecurityWebApplicationInitializer {	public SecurityWebApplicationInitializer() {        super(SecurityConfig.class);    }}

When our context startup, it uses ServletContext to add and register our configuration class as .

当我们的上下文启动时,它使用ServletContext添加并将我们的配置类注册为 。

Note that this will work only in Servlet-3 complaint servlet containers. So if you are using Apache Tomcat, make sure it’s version is 7.0 or higher.

注意,这仅在Servlet-3投诉Servlet容器中有效。 因此,如果您使用的是Apache Tomcat,请确保其版本为7.0或更高。

Our project is ready, just deploy it in your favorite servlet container. I am using Apache Tomcat-7 for running this application.

我们的项目已经准备就绪,只需将其部署在您喜欢的servlet容器中即可。 我正在使用Apache Tomcat-7来运行此应用程序。

Below images show the response in various scenarios.

下图显示了在各种情况下的响应。

在没有安全性的情况下访问HTML页面 (Accessing HTML Page without Security)

身份凭证验证失败 (Authentication Failed for Bad Credentials)

Spring Security JDBC身份验证首页 (Home Page with Spring Security JDBC Authentication)

带有Spring Security UserDetailsS​​ervice DAO身份验证的主页 (Home Page with Spring Security UserDetailsService DAO Authentication)

带有Spring Security内存身份验证的主页 (Home Page with Spring Security In-Memory Authentication)

登出页面 (Logout Page)

If you want to use Servlet Container that doesn’t support Servlet Specs 3, then you would need to register DispatcherServlet through deployment descriptor. See JavaDoc of WebApplicationInitializer for more details.

如果要使用不支持Servlet Specs 3的Servlet容器,则需要通过部署描述符注册DispatcherServlet 。 有关更多详细信息,请参见WebApplicationInitializer JavaDoc。

That’s all for Spring Security example tutorial and it’s integration in Servlet Based Web Application. Please download the sample project from below link and play around with it to learn more.

这就是Spring Security示例教程的全部内容,并将其集成到基于Servlet的Web应用程序中。 请从下面的链接下载示例项目并进行试用以了解更多信息。

翻译自:

转载地址:http://rmlzd.baihongyu.com/

你可能感兴趣的文章
购买《哈利波特》书籍
查看>>
谈谈一些网页游戏失败的原因到底有哪些?(转)
查看>>
备案的问题
查看>>
asp.net下ajax.ajaxMethod使用方法
查看>>
win10+mongodb安装配置
查看>>
window7修改hosts文件
查看>>
【Leetcode_easy】720. Longest Word in Dictionary
查看>>
地铁时光机第一阶段冲刺一
查看>>
Code Smell那么多,应该先改哪一个?
查看>>
站立会议02(一期)
查看>>
oracle数据库导入导出问题
查看>>
Android中的动画
查看>>
LeetCode 119 Pascal's Triangle II
查看>>
【Noip2015pj】求和
查看>>
深入理解JavaScript——闭包
查看>>
C#-WebForm-css box-shadow 给边框添加阴影效果
查看>>
objective-c 编程总结(第七篇)运行时操作 - 动态属性
查看>>
C_数据结构_链表
查看>>
kettle-连接控件
查看>>
Coursera--Neural Networks and Deep Learning Week 2
查看>>