分布式项目中SpringSecurity使用数据库中的密码登陆
一、导入依赖
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-cas</artifactId> </dependency>
二、配置文件
在web-shop项目下的resources目录下创建spring-security.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<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" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" 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"> <!-- 放行的资源--> <http pattern="/*.html" security="none"/> <http pattern="/css/**" security="none"/> <http pattern="/img/**" security="none"/> <http pattern="/js/**" security="none"/> <http pattern="/plugins/**" security="none"/> <http pattern="/seller/add.do" security="none"/> <!-- use-expressions:设置是否启动SpEL表达式,默认值是true。 --> <http use-expressions="false"> <!-- 配置SpringSecurity的拦截路径(拦截规则) * pattern:配置拦截规则。 /* 代表的是根路径下的所有资源(不包含子路径) /**代表的是根路径下所有的资源(包含子路径) * access:设置角色 角色命名 ROLE_角色名称 如: ROLE_USER --> <intercept-url pattern="/**" access="ROLE_SELLER"/> <!-- 开启表单验证 username-parameter="username" password-parameter="password" login-page :登录页面名称 以 / 开始 default-target-url :登录成功后跳转的页面 login-processing-url:提交的路径的设置 默认值"/login" 可以修改 --> <form-login login-page="/shoplogin.html" default-target-url="/admin/index.html" always-use-default-target="true" authentication-failure-url="/shoplogin.html"/> <!-- 不使用csrf的校验,系统可以使用跨域请求 --> <csrf disabled="true"/> <!-- 配置框架页面不拦截 --> <headers> <frame-options policy="SAMEORIGIN"/> </headers> <!-- 注销的配置 --> <logout logout-url="/logout" logout-success-url="/shoplogin.html" /> </http> <!-- 认证管理器 --> <authentication-manager> <authentication-provider user-service-ref="userDetailService"> </authentication-provider> </authentication-manager> <!-- 引用dubbo 服务 --> <dubbo:application name="pinyougou-shop-web" /> <dubbo:registry address="zookeeper://192.168.200.128:2181"/>
<!--注入服务提供者中的SellerService-->
<dubbo:reference id="sellerService" interface="cn.lqc.core.service.SellerService" > </dubbo:reference> <!-- 配置自定义的认证类 --> <beans:bean id="userDetailService" class="cn.lqc.core.service.UserDetailServiceImpl">
<!--创建SellerService对象-->
<beans:property name="sellerService" ref="sellerService"></beans:property> </beans:bean> </beans:beans>
注意:dubbo应用名称必须和SpringMVC.Xml配置的应用名称一致。
三、创建自定义类(在当前web-shop项目下创建)
(1)在youlexuan-shop-web创建com.offcn.service包,包下创建类UserDetailsServiceImpl.java 实现SpringSecurity的UserDetailsService接口,重写loadUserByUsername方法
package cn.lqc.core.service; import cn.lqc.core.pojo.seller.Seller; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import java.util.ArrayList; import java.util.List; public class UserDetailServiceImpl implements UserDetailsService { private SellerService sellerService; //由于在配置文件中已经存在sellerService对象,这里提供setter方法,注入到自定义类中来,获取服务提供者中的service public void setSellerService(SellerService sellerService){ this.sellerService = sellerService; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //构建角色列表 List<GrantedAuthority> grantAuths=new ArrayList<GrantedAuthority>(); grantAuths.add(new SimpleGrantedAuthority("ROLE_SELLER")); //得到商家对象,这里的username就是商家表主键sellerId Seller seller = sellerService.findOne(username); //商家必须是审核通过的 if(seller != null && "1".equals(seller.getStatus())){ return new User(username,seller.getPassword(),grantAuths); } return null; } }
四、前端登录页面
表单提交的actio属性中为:/login
<div id="profile" class="tab-pane active"> <form class="sui-form" id="loginForm" action="/login" method="post"> <div class="input-prepend"><span class="add-on loginname"></span> <input id="prependedInput" name="username" type="text" placeholder="邮箱/用户名/手机号" class="span2 input-xfat"> </div> <div class="input-prepend"><span class="add-on loginpwd"></span> <input id="prependedInput" name="password" type="password" placeholder="请输入密码" class="span2 input-xfat"> </div> <div class="setting"> <label class="checkbox inline"><input name="m1" type="checkbox" value="2" checked="">自动登录</label> <span class="forget">忘记密码?</span> </div> <div class="logined"> <a class="sui-btn btn-block btn-xlarge btn-danger" onclick="document.getElementById('loginForm').submit()" target="_blank">登 录</a> </div> </form>
五、在web-shop下创建一个自定义类来获取当前登陆用户
//从安全框架中获取正在登陆的用户名
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
package cn.lqc.core.controller; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/login") public class ShopLoginController { @RequestMapping("/showName") public Map<String,Object> showName(){ Map<String,Object> map = new HashMap<>(); //从安全框架中获取正在登陆的用户名 String name = SecurityContextHolder.getContext().getAuthentication().getName(); map.put("username",name); return map; } }
<!--扫描服务提供者中的SellerService-->