优质博文:IT-BLOG-CN

一、Spring Security 简介

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的 Bean,充分利用了Spring IoC,DI(控制反转 Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

二、Spring Security 入门Demo

【1】创建Maven工程(war形式):spring-security-demo 【2】修改pom.xml目录,如下:

4.12

4.2.4.RELEASE

4.0.0

2.5

2.8.4

3.4.7

0.1

3.2.8

1.2.2

1.2.15

5.1.32

1.0.9

1.3.1

2.3.23

5.11.2

3.2.3.RELEASE

4.10.3

2012_u6

org.springframework

spring-core

${spring.version}

org.springframework

spring-web

${spring.version}

org.springframework

spring-webmvc

${spring.version}

org.springframework

spring-context-support

${spring.version}

org.springframework

spring-test

${spring.version}

org.springframework

spring-jdbc

${spring.version}

org.springframework.security

spring-security-web

4.1.0.RELEASE

org.springframework.security

spring-security-config

4.1.0.RELEASE

javax.servlet

servlet-api

2.5

provided

org.apache.maven.plugins

maven-compiler-plugin

3.2

1.7

1.7

UTF-8

org.apache.tomcat.maven

tomcat7-maven-plugin

9090

/

注意:如果只是给自己的项目中嵌入Spring Security安全框架,只需要添加如下两个jar包即可。

org.springframework.security

spring-security-web

4.1.0.RELEASE

org.springframework.security

spring-security-config

4.1.0.RELEASE

【3】创建web.xml文件(通过Spring Security拦截需要处理的请求和引入Spring Security的配置文件)。

xmlns="http://java.sun.com/xml/ns/javaee"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

version="2.5">

contextConfigLocation

classpath:spring-security.xml

org.springframework.web.context.ContextLoaderListener

springSecurityFilterChain

org.springframework.web.filter.DelegatingFilterProxy

springSecurityFilterChain

/*

【4】创建Spring Security配置文件:spring-security.xml(与 web.xml中引入的配置文件对应),代码中有配置的详细说明注解。

xmlns="http://www.springframework.org/schema/security"

xmlns:beans="http://www.springframework.org/schema/beans"

xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd

http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

default-target-url="/index.html"

authentication-failure-url="/login_error.html"

always-use-default-target="true" />

【5】需要自己创建:login.html(登录页面 如下)、index.html(登录成功跳转页面)、login_error.html(登录失败跳转页面)

登陆

--欢迎登陆我的系统--

用户名:

密码:

三、项目实战中,后台业务逻辑实现重要代码摘取,供实战中使用

【1】配置文件中配置的,登录时用户名和密码的业务逻辑处理类(实现UserDetailsService:框架自带的接口),注意:普通demo不需要此部分,主要用于真是环境登录逻辑的处理。

public class UserDetailServiceImpl implements UserDetailsService {

//当通过配置文件的形式,引入服务类时需要设置set方法。

private SellerService sellerService;

public void setSellerService(SellerService sellerService) {

this.sellerService = sellerService;

}

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

//GrantedAuthority : 定义用户角色,需要实现的接口

List list =new ArrayList<>();

//用户添加角色,SimpleGrantedAuthority可以定义用户角色,实现了GrantedAuthority接口,

//格式必须以(ROLE_)开头

list.add(new SimpleGrantedAuthority("ROLE_SELLER"));

//从数据库中获取用户信息。

TbSeller seller = sellerService.findOne(username);

if(seller != null) {

//返回username:传过来的参数。seller.getPassword:数据库中获取到的用户密码。

//list:用户的所有角色,可以从数据库中获取

return new User(username, seller.getPassword(), list);

}else {

return null;

}

}

}

【2】BCrypt加密过程(配置中说明了BCrypt与MD5的区别)。

@RequestMapping("/add")

public Result add(@RequestBody TbSeller seller){

try {

//BCrypt加密使用的对象BCryptPasswordEncoder

BCryptPasswordEncoder cryptPasswordEncoder = new BCryptPasswordEncoder();

//使用encode方法对传入的密码加密,返回30位的字符串

String encode = cryptPasswordEncoder.encode(seller.getPassword());

//业务处理:接入对象中

seller.setPassword(encode);

//调用服务层,入库

sellerService.add(seller);

return new Result(true, "增加成功");

} catch (Exception e) {

e.printStackTrace();

return new Result(false, "增加失败");

}

}

四、当程序中需要用户名时,可通过 SecurityContextHolder 对象获取

☏ SecurityContextHolder用于存储安全上下文security context的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保存在SecurityContextHolder中。SecurityContextHolder默认使用ThreadLocal策略来存储认证信息。看到ThreadLocal也就意味着,这是一种与线程绑定的策略。Spring Security在用户登录时自动绑定认证信息到当前线程,在用户退出时,自动清除当前线程的认证信息。但这一切的前提,是你在web场景下使用Spring Security。

☏ 因为身份信息是与线程绑定的,所以可以在程序的任何地方使用静态方法获取用户信息。一个典型的获取当前登录用户的姓名的例子如下所示:getAuthentication() 返回了认证信息。

@RequestMapping("/name")

public Map getName(){

//获取登录名

String name = SecurityContextHolder.getContext().getAuthentication().getName();

Map map = new HashMap<>();

map.put("loginName", name);

return map;

}

☏ Authentication源码:

package org.springframework.security.core;// <1>

public interface Authentication extends Principal, Serializable { // <1>

Collection getAuthorities(); // <2>

Object getCredentials();// <2>

Object getDetails();// <2>

Object getPrincipal();// <2>

boolean isAuthenticated();// <2>

void setAuthenticated(boolean var1) throws IllegalArgumentException;

}

【1】Authentication 是Spring Security包中的接口,直接继承自Principal类,而Principal是位于java.security包中的。可以见得,Authentication在Spring Security中是最高级别的身份/认证的抽象。 【2】由这个顶级接口,我们可以得到用户拥有的权限信息列表,密码,用户细节信息,用户身份信息,认证信息。 authentication.getPrincipal()返回了一个 Object,我们将Principal强转成了Spring Security中最常用的UserDetails,这在Spring Security 中非常常见,接口返回Object,使用instanceof判断类型,强转成对应的具体实现类。接口详细解读如下:  ● getAuthorities():权限信息列表,默认是GrantedAuthority接口的一些实现类,通常是代表权限信息的一系列字符串。  ● getCredentials():密码信息,用户输入的密码字符串,在认证过后通常会被移除,用于保障安全。  ● getDetails():细节信息,web应用中的实现接口通常为WebAuthenticationDetails,它记录了访问者的ip地址和sessionId的值。  ● getPrincipal():最重要的身份信息,大部分情况下返回的是UserDetails接口的实现类,也是框架中的常用接口之一。

参考文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: