zoukankan      html  css  js  c++  java
  • 品优购_day04

    品优购_day04

    1. Spring Security框架

    1.1 Spring Security简介

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

    1.2 spring-security.xml

    <!--配置不拦截的资源-->
    	<security:http pattern="/login.html" security="none"></security:http>
    	<security:http pattern="/css/**" security="none"></security:http>
    	<security:http pattern="/img/**" security="none"></security:http>
    	<security:http pattern="/js/**" security="none"></security:http>
    	<security:http pattern="/plugins/**" security="none"></security:http>
    <!--页面拦截规则-->
    	<security:http use-expressions="false">
    		<!--配置具体的拦截规则-->
    		<security:intercept-url pattern="/**" access="ROLE_SELLER"/>
    		<!--定义跳转的具体页面-->
    		<security:form-login login-page="/login.html" 
    							login-processing-url="/login.do" 
    							default-target-url="/admin/index.html"
    							authentication-failure-url="/login.html"
    							always-use-default-target="true"/>
    		<!--关闭跨域请求-->
    		<security:csrf disabled="true"/>
    		<!--显示框架页-->
    		<security:headers>
    			<security:frame-options policy="SAMEORIGIN"/>
    		</security:headers>
    		
    		<!--用户退出-->
    		<security:logout invalidate-session="true" logout-url="/logout.do"/>
    	</security:http>
    
    <!-- 认证管理器 -->
    	<security:authentication-manager>
    		<security:authentication-provider>
    			<security:user-service>
    <!--可直接在这里配置用户名,密码,权限-->
    				<security:user name="admin" password="123" authorities="ROLE_SELLER"/>
    			</security:user-service>		
    		</security:authentication-provider>	
    	</security:authentication-manager>
    
    1. intercept-url 表示拦截页面

    /* 表示的是该目录下的资源,只包括本级目录不包括下级目录

    /** 表示的是该目录以及该目录下所有级别子目录的资源

    1. form-login :为开启表单登陆;

    login-processing-url:登录时提交的地址,默认为/login.do,可不写;

    default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面;

    authentication-failure-url:指定了身份验证失败时跳转到的页面;

    always-use-default-target:指定了是否在身份验证通过后总是跳转到default-target-url属性指定的URL。

    1. use-expressions 为是否使用使用 Spring 表达式语言( SpEL ),默认为ttrue ,如果开启,则拦截的配置应该写成以下形式

    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />

    1. <security:csrf disabled="true"/>:关闭跨域请求

    关闭csrf ,因为这里是html页面,如果不加会出现错误:Http status 403-Invalid CSRF token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN',如果是jsp页面,则不用关闭,要携带x-csrf-token头信息,必须是jsp页面。

    CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。

    1. <security:frame-options policy="SAMEORIGIN"/>

    如果你系统中使用了框架页,如adminLTE需要设置框架页的策略为SAMEORIGIN,框架页才会显示。

    1. <security:logout invalidate-session="true" logout-url="/logout.do"/>

    用于退出登录,添加此行,然后点击退出时访问/logout.do即可。invalidate-session:清空已定义的session ,而不是清空session里的值,logout-url:退出的地址,默认是/logout.do。

    1.3 登录页面

    <form id="loginForm" action="/login" method="post"  >
    		<input name="username" type="text" placeholder="邮箱/用户名/手机号" class="span2 input-xfat">
    		<input name="password" type="password" placeholder="请输入密码" class="span2 input-xfat">
    		<a onclick="document:loginForm.submit()" target="_blank">登录</a>
    </form>
    

    1.4 显示登录用户名

    可单独写一个LoginController,然后在页面初始化时访问即可。

    @RestController
    @RequestMapping("/login")
    public class LoginController {
    	@RequestMapping("/name")
    	public Map getLoginName() {
    	String loginName=
      SecurityContextHolder.getContext().getAuthentication().getName();
    		Map map=new HashMap();
    		map.put("loginName", loginName);
    		return map;
    	}
    }
    

    Spring Security使用一个Authentication对象来描述当前用户的相关信息。SecurityContextHolder中持有的是当前用户的SecurityContext,而SecurityContext持有的是代表当前用户相关信息的Authentication的引用,可以通过getName()或getPrincipal方法获取当前登录用户的用户名。getName()是直接获取当前线程的操作对象,框架已经封装进去, 而getPrincipal()需要自己实例化去判断,可以加入业务逻辑判断,再进行返回。

    2. 商家登录与安全控制

    完成商家系统登陆与安全控制,商家账号来自数据库,并实现密码加密。

    2.1 自定义认证类

    在pinyougou-shop-web创建com.pinyougou.service包,包下创建类UserDetailsServiceImpl.java 实现UserDetailsService接口

    public class UserServiceImpl implements UserDetailsService {
    	private SellerService ss;//不用注解方式,用配置方式注入时,必须有一个set方法
    	public void setSs(SellerService ss) {
    		this.ss = ss;
    	}
    	@Override
    	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
    		//构建角色列表
    		List<GrantedAuthority> list=new ArrayList();
    		list.add(new SimpleGrantedAuthority("ROLE_SELLER"));
    		//到数据库中查询用户
            TbSeller ts=ss.findOne(username);
    		if(ts!=null&&ts.getStatus().equals("1")) {
    			return new User(username,ts.getPassword(),list);
    		}
    		return null;
    	}
    }
    

    2.2 在spring-security.xml添加如下配置

    重难点:引用dubbo服务获取在远程的SellerService

    <!--不过滤添加用户操作-->
    <security:http pattern="/seller/add.do" security="none"></security:http>
    
    <!-- 认证管理器 -->
    	<!-- 切换成数据库中的用户名和密码 -->
        <security:authentication-manager>
            <security:authentication-provider user-service-ref="userService">
                <!-- 配置加密的方式 -->
    <security:password-encoder ref="bCryptPasswordEncoder"/>
            </security:authentication-provider>
        </security:authentication-manager>
    	
    	<!--配置认证类-->
    	<bean id="userService" class="com.pinyougou.service.UserServiceImpl">
    		<property name="ss" ref="sellerService"></property>
    	<!--name="ss"这个名字与UserServiceImpl中的ss相同-->
    </bean>
    	
    	<!--
    UserServiceImpl用到了SellerService,而UserServiceImpl在18pinyougou-shop-web,而SerllerService在18pinyougou-sellergoods-interface,即SellerService在远程,所以要引用dubbo服务获取-->
    	<!-- 引用dubbo 服务 -->
    	<dubbo:application name="18pinyougou-shop-web"></dubbo:application>
    	<dubbo:registry address="zookeeper://192.168.25.130:2181"></dubbo:registry>
    	<dubbo:reference id="sellerService" interface="com.pinyougou.sellergoods.service.SellerService"></dubbo:reference>
    

    2.3 密码加密

    2.3.1 BCrypt加密算法

    用户表的密码通常使用MD5等不可逆算法加密后存储,为防止彩虹表破解更会先使用一个特定的字符串(如域名)加密,然后再使用一个随机的salt(盐值)加密。 特定字符串是程序代码中固定的,salt是每个密码单独随机,一般给用户表加一个字段单独存储,比较麻烦。 BCrypt算法将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题。

    2.3.2 使用BCrypt进行加密存储

    创建密码加密工具类

    public class PasswordEncoderUtils {
    	private static BCryptPasswordEncoder bpe=new BCryptPasswordEncoder();
    	//返回加密后的密码
    	public static String passwordEncode(String password) {
    		return bpe.encode(password);
    	}
    }
    

    2.3.3 在spring-security.xml配置加密类

    <security:authentication-manager>
            ......
                <!-- 配置加密的方式 -->
    <security:password-encoder ref="bCryptPasswordEncoder"/>
            </security:authentication-provider>
    </security:authentication-manager>
    
    <!-- 配置加密类 -->
        <!--声明该加密类为一个名为bCryptPasswordEncoder的bean-->
        <bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
    
  • 相关阅读:
    Log4Net使用
    4月博文
    论坛题目练习
    职场冷笑话两则
    初识管理的一些心得
    Project中分清楚挣值项
    预留规划项
    小感触
    好事多磨,好事成双
    忧郁
  • 原文地址:https://www.cnblogs.com/ALiWang/p/12885069.html
Copyright © 2011-2022 走看看