谷歌官方建站服务,做商城网站服务器,discuz社区动力,html5如何实现网站开发优质博文#xff1a;IT-BLOG-CN
一、Spring Security 简介
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的 Bean#xff0c;充分利用了Spring IoC#xff0c;DI#xff0…优质博文IT-BLOG-CN
一、Spring Security 简介
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的 Bean充分利用了Spring IoCDI控制反转 Inversion of Control DIDependency Injection 依赖注入和AOP面向切面编程功能为应用系统提供声明式的安全访问控制功能减少了为企业系统安全控制编写大量重复代码的工作。
二、Spring Security 入门Demo
【1】创建Maven工程war形式spring-security-demo 【2】修改pom.xml目录如下
!-- 集中定义依赖版本号 --
propertiesjunit.version4.12/junit.versionspring.version4.2.4.RELEASE/spring.versionpagehelper.version4.0.0/pagehelper.versionservlet-api.version2.5/servlet-api.versiondubbo.version2.8.4/dubbo.versionzookeeper.version3.4.7/zookeeper.versionzkclient.version0.1/zkclient.version mybatis.version3.2.8/mybatis.versionmybatis.spring.version1.2.2/mybatis.spring.versionmybatis.paginator.version1.2.15/mybatis.paginator.versionmysql.version5.1.32/mysql.version druid.version1.0.9/druid.versioncommons-fileupload.version1.3.1/commons-fileupload.versionfreemarker.version2.3.23/freemarker.versionactivemq.version5.11.2/activemq.versionsecurity.version3.2.3.RELEASE/security.version solrj.version4.10.3/solrj.versionik.version2012_u6/ik.version
/properties
dependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-core/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-web/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-context-support/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework.security/groupIdartifactIdspring-security-web/artifactIdversion4.1.0.RELEASE/version/dependencydependencygroupIdorg.springframework.security/groupIdartifactIdspring-security-config/artifactIdversion4.1.0.RELEASE/version/dependencydependencygroupIdjavax.servlet/groupIdartifactIdservlet-api/artifactIdversion2.5/versionscopeprovided/scope/dependency/dependencies
buildplugins!-- java编译插件 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.2/versionconfigurationsource1.7/sourcetarget1.7/targetencodingUTF-8/encoding/configuration/pluginplugingroupIdorg.apache.tomcat.maven/groupIdartifactIdtomcat7-maven-plugin/artifactIdconfiguration!-- 指定端口 --port9090/port!-- 请求路径 --path//path/configuration/plugin/plugins
/build注意如果只是给自己的项目中嵌入Spring Security安全框架只需要添加如下两个jar包即可。
dependencygroupIdorg.springframework.security/groupIdartifactIdspring-security-web/artifactIdversion4.1.0.RELEASE/version
/dependencydependencygroupIdorg.springframework.security/groupIdartifactIdspring-security-config/artifactIdversion4.1.0.RELEASE/version
/dependency【3】创建web.xml文件通过Spring Security拦截需要处理的请求和引入Spring Security的配置文件。
?xml version1.0 encodingUTF-8?
web-app xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlnshttp://java.sun.com/xml/ns/javaeexsi:schemaLocationhttp://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsdversion2.5 !-- 引入spring-security框架的配置文件 --context-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:spring-security.xml/param-value/context-paramlistenerlistener-classorg.springframework.web.context.ContextLoaderListener/listener-class/listener!-- 通过spring-security 内置的拦截器 springSecurityFilterChain 拦截 /* 的请求,名称不能修改安全框架的入口配置 --!-- 所有的请求通过拦截器(DelegatingFilterProxy)拦截后,找名为 springSecurityFilterChain 类进行逻辑处理此类是spring security安全框架中所包含的类 --filter filter-namespringSecurityFilterChain/filter-name filter-classorg.springframework.web.filter.DelegatingFilterProxy/filter-class /filter filter-mapping filter-namespringSecurityFilterChain/filter-name url-pattern/*/url-pattern /filter-mapping
/web-app【4】创建Spring Security配置文件spring-security.xml与 web.xml中引入的配置文件对应代码中有配置的详细说明注解。
?xml version1.0 encodingUTF-8?
!-- 此配置将Spring Seucrity设置成了默认标签其他使用时需要添加如下前缀beans或dubbo等 --
beans:beansxmlnshttp://www.springframework.org/schema/securityxmlns:beanshttp://www.springframework.org/schema/beansxmlns:dubbohttp://code.alibabatech.com/schema/dubboxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd!-- 登录页面不能拦截 none任何角色都可访问如果你没有设置登录页securitynone 将会出现以下错误 :重定向次数过多因为登录页会被反复重定向--http pattern/*.html securitynone/httphttp pattern/css/** securitynone/httphttp pattern/img/** securitynone/httphttp pattern/js/** securitynone/httphttp pattern/plugins/** securitynone/http!-- 注意如果是用户申请登录名的请求也不能拦截 --http pattern/seller/add.do securitynone/http!-- 拦截页面 --!-- use-expressions -为是否使用 Spring 表达式语言 SpEL 默认为true ,如果开启则拦截的配置应该写成以下形式intercept-url pattern/** accesshasRole(ROLE_USER) /--http use-expressionsfalse!-- /* 表示的是该目录下的资源只包括本级目录不包括下级目录/** 表示的是该目录以及该目录下所有级别子目录的资源--intercept-url pattern/** accessROLE_SELLER /!-- form-login开启表单登录默认登录请求/login可以通过配置修改默认请求always-use-default-target指定了是否在身份验证通过后总是跳转到default-target-url属性指定的URL。authentication-failure-url:登录失败跳转页面 --form-login login-page/login.htmldefault-target-url/index.htmlauthentication-failure-url/login_error.htmlalways-use-default-targettrue /!-- csrf disabledtrue 关闭csrf ,如果不加会出现错403 这种一般会自动生成在请求头信息中X-CSRF-TOKEN(相当于一个校徽)防止跨站点攻击但只能jsp实现html不能实现因此需要关闭此功能 CSRFCross-site request forgery跨站请求伪造也被称为“One Click Attack”或者Session Riding通常缩写为CSRF或者XSRF是一种对网站的恶意利用。--csrf disabledtrue /!-- 当页面中存在嵌入式iframe时需要配置hears --headersframe-options policySAMEORIGIN //headers!-- 登出页面只需要发送/logout请求就可会触发 也可以修改默认的处理例如logout-url可以修改登出的请求--logout //http!-- Spring Security中 用户登录时认证管理器 --!-- Spring Security是如何完成身份认证的①、用户名和密码被过滤器获取到封装成Authentication,通常情况下是UsernamePasswordAuthenticationToken这个实现类。②、AuthenticationManager 身份管理器负责验证这个Authentication。③、认证成功后AuthenticationManager身份管理器返回一个被填充满了信息的包括上面提到的权限信息身份信息细节信息但密码通常会被移除Authentication实例。④、SecurityContextHolder安全上下文容器将第3步填充了信息的Authentication通过SecurityContextHolder.getContext().setAuthentication(…)方法设置到其中。 --authentication-manager!-- user-service-ref 指向用户认证业务处理类需要实现UserDetailsService接口--!-- 如果测试不想从数据库中获取用户可以直接配置一个用户名和密码 特换掉如下authentication-provider内的配置即可。 --authentication-provideruser-serviceuser nameadmin password123456 authoritiesROLE_USER//user-service/authentication-provider!-- authentication-provider user-service-refuserDetailServiceImpl对密码进行bcrypt加密比较时需要解密后处理bcrypt与MD5不同MD5加密后相同的密码生成相同的16位字符创bcrybt相同的密码加密后生成不同的30位字符串相当于MD5盐password-encoder hashbcrypt/password-encoder/authentication-provider --/authentication-manager!-- beans:bean iduserDetailServiceImpl classcom.pinyougou.shop.service.UserDetailServiceImpl当自己的项目需要使用另一个项目中的服务类时 需要通过dubbo引入项目 dubbo标签beans:property namesellerService refsellerService/beans:property/beans:bean --!-- 引用dubbo sellerService服务供登录用户业务处理类使用 --!-- dubbo:application namepinyougou-shop-web /dubbo:registry addresszookeeper://192.168.159.129:2181 /dubbo:reference idsellerServiceinterfacecom.pinyougou.sellergoods.service.SellerService/dubbo:reference --
/beans:beans【5】需要自己创建login.html登录页面 如下、index.html登录成功跳转页面、login_error.html登录失败跳转页面
!DOCTYPE html
html
head
meta charsetUTF-8
title登陆/title
/head
body--欢迎登陆我的系统--form action/login methodpost用户名input nameusernamebr密码input namepasswordbrbutton登陆/button/form
/body
/html三、项目实战中后台业务逻辑实现重要代码摘取供实战中使用
【1】配置文件中配置的登录时用户名和密码的业务逻辑处理类实现UserDetailsService框架自带的接口注意普通demo不需要此部分主要用于真是环境登录逻辑的处理。
public class UserDetailServiceImpl implements UserDetailsService {//当通过配置文件的形式引入服务类时需要设置set方法。private SellerService sellerService;public void setSellerService(SellerService sellerService) {this.sellerService sellerService;}Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//GrantedAuthority : 定义用户角色需要实现的接口ListGrantedAuthority 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加密使用的对象BCryptPasswordEncoderBCryptPasswordEncoder 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 MapString, String getName(){//获取登录名String name SecurityContextHolder.getContext().getAuthentication().getName();MapString, String map new HashMap();map.put(loginName, name);return map;
}☏ Authentication源码
package org.springframework.security.core;// 1
public interface Authentication extends Principal, Serializable { // 1Collection? extends GrantedAuthority getAuthorities(); // 2Object getCredentials();// 2Object getDetails();// 2Object getPrincipal();// 2boolean isAuthenticated();// 2void 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接口的实现类也是框架中的常用接口之一。