Spring Security 示例教程

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

目录[ 隐藏 ]

  • 1 Spring Security

    • 1.1 Spring安全示例
    • 1.2 Spring Security Maven依赖
    • 1.3 Spring安全示例查看页面
    • 1.4 Spring安全示例UserDetailsS​​ervice DAO实现
    • 1.5 Spring安全示例WebSecurityConfigurer实现
    • 1.6将Spring Security Web与Servlet API集成
      • 1.6.1在没有安全性的情况下访问HTML页面
      • 1.6.2认证证书失败认证失败
      • 1.6.3具有Spring Security JDBC身份验证的主页
      • 1.6.4具有Spring Security UserDetailsS​​ervice DAO身份验证的主页
      • 1.6.5具有Spring Security内存中认证的主页
      • 1.6.6注销页面

春季安全


使用Spring Security的一些好处是:

  1. 经过验证的技术,使用它比重新发明轮子更好。安全性是我们需要特别小心的事情,否则我们的应用程序将容易受到攻击者的攻击。
  2. 防止一些常见攻击,如CSRF,会话固定攻击。
  3. 易于集成到任何Web应用程序中。我们不需要修改Web应用程序配置,spring会自动将安全过滤器注入Web应用程序。
  4. 通过不同方式提供对身份验证的支持 - 内存,DAO,JDBC,LDAP等等。
  5. 提供忽略特定URL模式的选项,适用于提供静态HTML,图像文件。
  6. 支持组和角色。

Spring安全示例

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

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

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

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

  1. 在记忆中
  2. DAO
  3. JDBC

对于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;

我们还需要在我们的servlet容器中将JDBC DataSource配置为JNDI,要了解这一点,请阅读Tomcat JNDI DataSource示例。

Spring Security Maven依赖项

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


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>WebappSpringSecurity</groupId><artifactId>WebappSpringSecurity</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><dependencies><!-- Spring Security Artifacts - START --><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>3.2.3.RELEASE</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>3.2.3.RELEASE</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-taglibs</artifactId><version>3.0.5.RELEASE</version></dependency><!-- Spring Security Artifacts - END --><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version><scope>compile</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version><scope>provided</scope></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>4.0.2.RELEASE</version></dependency></dependencies><build><sourceDirectory>src</sourceDirectory><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>1.7</source><target>1.7</target></configuration></plugin><plugin><artifactId>maven-war-plugin</artifactId><version>2.3</version><configuration><warSourceDirectory>WebContent</warSourceDirectory><failOnMissingWebXml>false</failOnMissingWebXml></configuration></plugin></plugins></build>
</project>

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

  1. spring-jdbc:这用于JDBC身份验证方法的JDBC操作。它需要将DataSource设置为JNDI。有关它的用法的完整示例,请参阅Spring DataSource JNDI示例
  2. spring-security-taglibs:Spring Security标记库,我用它在JSP页面中显示用户角色。大多数时候,你不会需要它。
  3. spring-security-config:用于配置身份验证提供程序,是否使用JDBC,DAO,LDAP等。
  4. spring-security-web:该组件将Spring Security与Servlet API集成在一起。我们需要它来在Web应用程序中插入我们的安全配置。

另请注意,我们将使用Servlet API 3.0功能通过编程方式添加侦听器和过滤器,这就是依赖项中的servlet api版本应为3.0或更高的原因。

Spring安全示例查看页面

我们的应用程序中有JSP和HTML页面。我们希望在除HTML页面之外的所有页面中应用身份验证。

health.html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Health Check</title>
</head>
<body><h3>Service is up and running!!</h3>
</body>
</html>

index.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Home Page</title>
</head>
<body>
<h3>Home Page</h3><p>Hello <b><c:out value="${pageContext.request.remoteUser}"/></b><br>Roles: <b><sec:authentication property="principal.authorities" /></b></p><form action="logout" method="post"><input type="submit" value="Logout" /><input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/></form>
</body>
</html>

我已经包括index.jspwelcome-file在应用程序部署描述符。

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

我们现在来看看Spring Security配置。

Spring安全示例UserDetailsS​​ervice DAO实现

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

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

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());@Overridepublic 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 operationsreturn new UserDetails() {private static final long serialVersionUID = 2059202961588104658L;@Overridepublic boolean isEnabled() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic String getUsername() {return username;}@Overridepublic String getPassword() {return "pankaj123";}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {List<SimpleGrantedAuthority> auths = new java.util.ArrayList<SimpleGrantedAuthority>();auths.add(new SimpleGrantedAuthority("admin"));return auths;}};}}

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

Spring安全示例WebSecurityConfigurer实现

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

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
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overridepublic 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 JDBCContext 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);}@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring()// Spring Security should completely ignore URLs ending with .html.antMatchers("/*.html");}}

请注意,我们通过重写configure(WebSecurity web)方法忽略所有HTML文件。

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

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

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

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

将Spring Security Web与Servlet API集成

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

SecurityWebApplicationInitializer.java


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

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

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

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

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

无安全地访问HTML页面

身份验证失败的身份验证失败

具有Spring Security JDBC身份验证的主页

具有Spring Security UserDetailsS​​ervice DAO身份验证的主页

具有Spring Security内存中认证的主页

退出页面

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

这就是Spring Security示例教程以及它在基于Servlet的Web应用程序中的集成。请从下面链接下载示例项目并使用它来了解更多信息。

下载Spring Servlet Security 项目

Spring Security 示例教程相关推荐

  1. Spring Security示例教程

    Spring Security provides ways to perform authentication and authorization in a web application. We c ...

  2. java ldap操作实例_Java Spring Security示例教程中的2种设置LDAP Active Directory身份验证的方法...

    java ldap操作实例 LDAP身份验证是世界上最流行的企业应用程序身份验证机制之一,而Active Directory (Microsoft为Windows提供的LDAP实现)是另一种广泛使用的 ...

  3. Java Spring Security示例教程中的2种设置LDAP Active Directory身份验证的方法

    LDAP身份验证是全球范围内最流行的企业应用程序身份验证机制之一,而Active Directory (Microsoft针对Windows的LDAP实现)是另一种广泛使用的LDAP服务器. 在许多项 ...

  4. Spring安全示例教程

    Spring安全示例教程 Spring Security提供了在Web应用程序中执行身份验证和授权的方法.我们可以在任何基于servlet的Web应用程序中使用spring security. 目录[ ...

  5. Spring Security 示例UserDetailsS​​ervice

    Spring Security示例UserDetailsS​​服务 欢迎使用UserDetailsS​​ ervice的Spring安全性示例.在上一篇文章中,我们学习了如何在Web应用程序中使用Sp ...

  6. Spring Batch示例教程

    Spring Batch示例教程 欢迎使用Spring Batch示例.Spring Batch是一个用于执行批处理作业的弹簧框架模块.我们可以使用spring批处理来处理一系列作业. 目录[ 隐藏  ...

  7. Spring IoC,Spring Bean示例教程

    Spring IoC,Spring Bean示例教程 欢迎来到Spring IoC示例教程.Spring Framework基于Inversion of Control原理.依赖注入是在应用程序中实现 ...

  8. Spring AOP示例教程 - Aspect,Advice,Pointcut,JoinPoint,Annotations,XML Configuration

    Spring AOP示例教程 - Aspect,Advice,Pointcut,JoinPoint,Annotations,XML Configuration Spring Framework是基于两 ...

  9. Spring Security系列教程03--创建SpringSecurity项目

    前言 在上一章节中,一一哥 已经带大家认识了Spring Security,对其基本概念已有所了解,但是作为一个合格的程序员,最关键的肯定还是得动起手来,所以从本篇文章开始,我就带大家搭建第一个Spr ...

最新文章

  1. 正则表达式校验IP地址
  2. winxp ie8.0 html5,(IE8)Internet Explorer 8.0 For WinXP 简体中文正式版
  3. 维纳滤波原理(Wiener Filter)
  4. Java类库及其组织结构(Java API)
  5. android studio编译慢的问题
  6. 实现自己的.NET Core配置Provider之Yaml
  7. React类里面能写的东西
  8. Android 驱动(3)---Android驱动开发知识储备
  9. if函数python_关于函数:如何在python中为一个if语句提供多个条件
  10. ROS保姆级0基础入门教程⭐ |第一章 ROS的概述与环境搭建(4万字教程,建议收藏)
  11. 2018年大数据趋势丨大数据的黄金时代
  12. bin 文件分析(转)
  13. 手机通过WiFi控制电脑
  14. 如何将多个txt文件合并成一个文本?
  15. 自助图书馆系统-Tkinter界面和openpyxl表格综合设计案例
  16. 装机配置相关---激活win7旗舰版 office
  17. 停止在csdn发文及上传资源的声明
  18. debian ELK6.2.2安装教程
  19. 腾讯云服务器80等端口无法访问
  20. 光纤到桌面即FTTD综合布线方法

热门文章

  1. 关于C#函数对象参数传递的问题
  2. 使用 node.js 进行服务器端 JavaScript 编程
  3. Magento 产品推荐 extension Featured products 2.0 – revamped!
  4. 剑指offer14 1.剪绳子
  5. 【AI视野·今日NLP 自然语言处理论文速览 第二十二期】Mon, 27 Sep 2021
  6. ==和equals()比较
  7. ado.net的操作查询数据 0127
  8. Java 控制台程序的基本结构测试分析草稿
  9. django-学生列表页的制作
  10. mysql-演练0722