在使用Spring Security配置Web应用之前,首先要准备一个基于Maven的Spring框架创建的Web应用(Spring MVC不是必须的),本文的内容都是基于这个前提下的。

pom.xml添加依赖

除了Spring框架本身的一些依赖包,还需要在pom.xml中添加Spring Security的依赖包:

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>

入门环境配置

要想使用Spring Security,首先需要在web.xml配置一个过滤器,注意过滤器的filter-name必须是springSecurityFilterChain

1
2
3
4
5
6
7
8
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

另外还需要配置Spring Security配置文件,并将这个文件添加到Spring Application Context中。下面是一个最基本的Spring Security配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">

<http use-expressions="false">
<!-- 访问所有页面都需要有USER权限 -->
<intercept-url pattern="/**" access="ROLE_USER" />
<!-- 登录功能 -->
<form-login />
<!-- 登出功能 -->
<logout />
</http>

<authentication-manager>
<authentication-provider>
<user-service>
<!-- 这里创建两个用户,可以通过用户名密码登录 -->
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobspassword" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>

</beans:beans>

只需完成以上两个配置,启动服务器,用浏览器打开这个Web应用的任意一个页面,都会跳转到一个登录页,这个登录页面是Spring Security自动生成的。
Spring
Security默认登录页面

在登录页面输入错误的用户名密码,就会登录失败并有提示。输入正确的用户名密码,则登录成功,就可以进入Web应用的页面。一个最简单的基于Spring Security的Web应用已经完成!

指定登录页面

由于Spring Security默认的登录页面非常简陋,一般不会直接使用,通常会指定一个自定义的登录页面,例如指定一个自己的登录页/login.jsp

1
2
3
4
5
6
7
8
9
10
<http use-expressions="false">
<!-- 登录页面不需要控制权限 -->
<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<!-- 访问其他所有页面都需要有USER权限 -->
<intercept-url pattern="/**" access="ROLE_USER" />
<!-- 配置登录页面地址login-page、登录失败后的跳转地址authentication-failure-url -->
<form-login login-page='/login.jsp' authentication-failure-url='/login.jsp?error' />
<!-- 登出功能 -->
<logout />
</http>

自定义的登录页面jsp中的登录表单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<c:url value="/login" var="loginUrl" />
<form action="${loginUrl}" method="post">
<c:if test="${param.error != null}">
<p>Invalid username and password.</p>
</c:if>
<c:if test="${param.logout != null}">
<p>You have been logged out.</p>
</c:if>
<p>
<label for="username">Username</label>
<input type="text" id="username" name="username" />
</p>
<p>
<label for="password">Password</label>
<input type="password" id="password" name="password" />
</p>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<button type="submit" class="btn">Log in</button>
</form>

登录表单提交的页面地址是/login,method是POST请求,登录请求需要提交usernamepassword两个参数。为了安全,防止恶意的CSRF攻击,Spring Security需要校验form表单中的hidden域提交的内容。

登出

Spring Security配置文件中的<logout />用于处理登出。

页面中的登出按钮:

1
2
3
4
5
<c:url value="/logout" var="logoutUrl" />
<form action="${logoutUrl}" method="post">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<input type="submit" value="退出" />
</form>

登出请求地址/logout,method是POST请求。

登录用户信息从数据库获取

上文的登录用户的用户名、密码、ROLE都是配置在Spring Security的xml配置文件中的,在实际使用中,一般不会将用户信息直接配置在xml文件中,而是通过其他方式获取,例如数据库。

Spring Security提供了一个便捷的方式通过数据库获取用户信息,即org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl,它是org.springframework.security.core.userdetails.UserDetailsService接口的一个实现类,只要配置相关的DataSource和SQL语句就能从数据库获取到用户信息:

1
2
3
4
5
6
7
8
<authentication-manager>
<authentication-provider user-service-ref='userDetailsService' />
</authentication-manager>
<beans:bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="usersByUsernameQuery" value="select username, password, true from t_user where username = ?" />
<beans:property name="authoritiesByUsernameQuery" value="select username, role from t_user_role where username = ?" />
</beans:bean>

以上配置还可以简化为:

1
2
3
4
5
6
7
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username, password, true from t_user where username = ?"
authorities-by-username-query="select username, role from t_user_role where username = ?" />
</authentication-provider>
</authentication-manager>

登录用户信息通过其他方式获取

如果用户信息的来源并不是数据库,那么就需要自己实现org.springframework.security.core.userdetails.UserDetailsService接口的loadUserByUsername方法,即通过用户名获取用户信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class UserDetailsServiceImpl implements UserDetailsService {

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 以下可以替换成用其他方式获取用户信息
if(username.equals("xxg")) {
Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
auths.add(authority);
User user = new User(username, "123456", auths);
return user;
} else {
throw new UsernameNotFoundException("用户不存在");
}
}
}

将该实现类配置在Spring Security配置文件中:

1
2
3
4
<authentication-manager>
<authentication-provider user-service-ref='userDetailsService' />
</authentication-manager>
<beans:bean id="userDetailsService" class="com.xxg.UserDetailsServiceImpl" />

密码加密

明文保存密码通常是不安全的,在Spring Security中可以配置密码的加密方法。下面以MD5加密密码为例。

针对密码加密,Spring Security提供了org.springframework.security.crypto.password.PasswordEncoder接口。我们需要实现PasswordEncoder接口,实现我们自定义的加密方法,这样Spring Security在接收到用户登录请求后,会调用这个实现类,从而判断密码是否正确:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class PasswordEncoderImpl implements PasswordEncoder {

@Override
public String encode(CharSequence rawPassword) {
try {
// MD5加密密码
return DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}

@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return encode(rawPassword).equals(encodedPassword);
}
}

在Spring Security配置文件中配置上面的实现类:

1
2
3
4
5
6
7
<authentication-manager>
<authentication-provider>
<password-encoder ref="passwordEncoder" />
...
</authentication-provider>
</authentication-manager>
<beans:bean id="passwordEncoder" class="com.xxg.PasswordEncoderImpl" />

配置不受Spring Security管理的URL

如果Web应用中有某些URL不需要被Spring Security管理,例如一些静态文件,或者无需登录即可查看的页面,可以对这些URL配置security="none"

1
2
3
4
5
6
7
8
<http pattern="/resources/css/**" security="none"/>
<http pattern="/resources/images/**" security="none"/>
<http pattern="/resources/js/**" security="none"/>
<http use-expressions="false">
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login />
<logout />
</http>

禁用CSRF防御

Spring Security默认启用CSRF防御,要求每个POST请求都要都要带上CSRF token参数,如果感觉比较麻烦或者网站安全性要求不高,可以配置禁用:

1
2
3
4
<http use-expressions="false">
...
<csrf disabled="true" />
</http>

获取登录用户信息

获取用户名:

1
2
httpServletRequest.getRemoteUser();  // Servlet标准,推荐使用
SecurityContextHolder.getContext().getAuthentication().getName();

获取用户ROLE:

1
SecurityContextHolder.getContext().getAuthentication().getAuthorities();

判断用户是否拥有ROLE:

1
httpServletRequest.isUserInRole("ADMIN");

Spring Security Web应用入门环境搭建的更多相关文章

  1. Spring MVC+Spring+Mybatis+MySQL(IDEA)入门框架搭建

    目录 Spring MVC+Spring+Mybatis+MySQL(IDEA)入门框架搭建 0.项目准备 1.数据持久层Mybatis+MySQL 1.1 MySQL数据准备 1.2 Mybatis ...

  2. ArcGIS API for Silverlight/ 开发入门 环境搭建

    Silverlight/ 开发入门 环境搭建1 Silverlight SDK下载ArcGIS API for Microsoft Silverlight/WPF ,需要注册一个ESRI Gloab ...

  3. spring-security-4 (2)spring security 基于Java配置的搭建

    一.spring security的模块 搭建spring security首先我们要导入必须的jar,即maven的依赖.spring security按模块划分,一个模块对应一个jar. spri ...

  4. Windows C#入门环境搭建

    Windows C#入门环境搭建 1. 安装Microsoft .NET Framework目录: C:\Windows\Microsoft.NET\Framework,查看已经安装的版本. 如果未安 ...

  5. Android开发使用控件入门--环境搭建

    Android开发使用控件入门--环境搭建 软件名称(,梦,,想.CAD  ,控件) 1. 环境搭建: 3 1.1. 安装Eclipse 3 1.2. 下载JDK 3 1.3. 下载Android S ...

  6. 57.NodeJS入门--环境搭建 IntelliJ IDEA

    转自:https://blog.csdn.net/wang19891106/article/details/51127133 NodeJS入门–环境搭建 IntelliJ IDEA 本人也刚开始学习N ...

  7. NodeJS入门--环境搭建 IntelliJ IDEA

    NodeJS入门–环境搭建 IntelliJ IDEA 本人也刚开始学习NodeJS,所以以此做个笔记,欢迎大家提出意见. 1.首先 下载安装NodeJS,下载安装IntelliJ IDEA 2.接下 ...

  8. Spring Security极简入门三部曲(上篇)

    目录 Spring Security极简入门三部曲(上篇) 写在前面 为什么要用Spring Security 数据库设计 demo时刻 核心代码讲解 小结 Spring Security极简入门三部 ...

  9. Spring Security极简入门三部曲(中篇)

    目录 Spring Security极简入门三部曲(中篇) 验证流程 Authentication接口 过滤器链 AuthenticationProvider接口: demo时刻 代码讲解 小结 Sp ...

随机推荐

  1. Codeforces Round #563 (Div. 2) F. Ehab and the Big Finale

    后续: 点分治标程 使用father数组 比使用vis数组优秀(不需要对vis初始化) https://codeforces.com/problemset/problem/1174/F https:/ ...

  2. 用连接池链接redis

    package com.itheima.utils; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; i ...

  3. 尚学python课程---11、linux环境下安装python注意

    尚学python课程---11.linux环境下安装python注意 一.总结 一句话总结: 准备安装依赖包:zlib.openssl:yum install zlib* openssl*:pytho ...

  4. getResourceAsStream的几种路径配置(properties文件的路径问题)

    文章目录 getResourceAsStream有以下几种: getResourceAsStream有以下几种: Class.getResourceAsStream(String path) : pa ...

  5. ASP.NET自定义Validform的datatype

    1.定义 <script type="text/javascript"> $(function () { $("#aa").Validform({ ...

  6. QT 在QTabWidget中设置一些调色板

    这次所做的项目中需要用到如下功能,点击tableWidget中的子项,将会弹出颜色选值对话框,实现子项的改变,如下图所示: 1.首先,将自己定制的调色板放入tableWidget中 for (int ...

  7. apache反向代理和监听多个端口设置

    修改apache配置文件httpd.conf 一.监听多个端口 在Listen 80后添加监听端口,如 Listen 80 Listen 8080 Listen 8008 二.反向代理设置 1.取消一 ...

  8. 【默默努力】h5-game-blockBreaker

    先放下游戏的效果,我不太会玩游戏 然后放下无私开源的作者大大的地址:https://github.com/yangyunhe369/h5-game-blockBreaker 这个游戏的话,我觉得应该是 ...

  9. openSUSE中启用apache mod_rewrite

    1. 编辑 "/etc/sysconfig/apache2"文件 查找 APACHE_MODULES,你应该会找到一行像 APACHE_MODULES="actions ...

  10. loj2513 治疗之雨

    题意:你的英雄一开始血量为p,你还有m个队友,血量无穷.血量上限为n,下限为0.如果血量满了就不能加血.每次启动操作,随机给m+1个英雄加1点血,然后等概率随机k次每次对于英雄扣1点血.求期望操作几次 ...