近期做一个Oauth2的demo,搭建了一个小的框架,记录下来方便自己学习。框架是基于maven管理,使用Intellij Idea搭建起来的。没有使用maven的模板管理,直接用Idea新建的project。
Intellij Idea新建maven项目示例
MavenProjectRoot(项目根目录)的pom如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.xzgroupId>
<artifactId>mavenDemoartifactId>
<packaging>pompackaging>
<version>1.0-SNAPSHOTversion>
<properties>
<spring.version>4.3.7.RELEASEspring.version>
<mysql.version>5.1.7mysql.version>
<conmons-lang.version>2.4conmons-lang.version>
<servlet-api.version>2.4servlet-api.version>
<jsp-api>2.1jsp-api>
properties>
<modules>
<module>securitymodule>
modules>
<name>security Maven Webappname>
<url>http://maven.apache.orgurl>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-ormartifactId>
<version>3.2.7.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aopartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>com.mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
<dependency>
<groupId>commons-dbcpgroupId>
<artifactId>commons-dbcpartifactId>
<version>1.4version>
dependency>
<dependency>
<groupId>commons-langgroupId>
<artifactId>commons-langartifactId>
<version>${conmons-lang.version}version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>${servlet-api.version}version>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>${jsp-api}version>
dependency>
<dependency>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.0.17version>
dependency>
<dependency>
<groupId>com.yinhaigroupId>
<artifactId>ibatisartifactId>
<version>2.0version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>1.7.12version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>1.7.12version>
dependency>
<dependency>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
<version>1.2version>
dependency>
dependencies>
<build>
<finalName>securityfinalName>
<plugins>
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<version>2.3.2version>
<configuration>
<source>1.7source>
<target>1.7target>
<encoding>UTF-8encoding>
configuration>
plugin>
<plugin>
<artifactId>maven-surefire-pluginartifactId>
<version>2.7version>
<configuration>
<skipTests>trueskipTests>
<testFailureIgnore>truetestFailureIgnore>
configuration>
plugin>
<plugin>
<artifactId>maven-enforcer-pluginartifactId>
<version>1.1version>
<executions>
<execution>
<id>enforce-toolsid>
<goals>
<goal>enforcegoal>
goals>
<configuration>
<rules>
<requireJavaVersion>
<version>[1.7.0,)version>
requireJavaVersion>
<requireMavenVersion>
<version>[3.0.2,)version>
requireMavenVersion>
rules>
configuration>
execution>
executions>
plugin>
plugins>
build>
project>
新建module,pom.xml如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>mavenDemoartifactId>
<groupId>com.xzgroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>securityartifactId>
<packaging>warpackaging>
<name>security Maven Webappname>
<url>http://maven.apache.orgurl>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.28version>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-configartifactId>
<version>4.0.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-coreartifactId>
<version>4.0.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-taglibsartifactId>
<version>4.0.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-webartifactId>
<version>4.0.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.securitygroupId>
<artifactId>spring-security-aclartifactId>
<version>4.0.4.RELEASEversion>
dependency>
dependencies>
<build>
<finalName>securityfinalName>
build>
project>
新建的module包结构遵循maven项目标准结构,配置好sources,Resources,test,web后开始spring的配置,新建spring-context.xml做完spring的主配置文件。使用context:property-placeholder标签将properties文件加载到Spring配置文件中
<context:property-placeholder ignore-unresolvable="true"
location="classpath:config.properties,
classpath:jdbc.properties"/>
上面的配置等价于下面的配置,配置后可以通过${}获取properties的值
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config.propertiesvalue>
<value>classpath:jdbc.propertiesvalue>
list>
property>
bean>
新建spring-mvc.xml,项目使用注解,通过context-component-scan开启包路径扫描。注意在配置文件中使用 context 命名空间之前,必须在 元素中声明 context 命名空间。
xmlns:context="http://www.springframework.org/schema/context"
<context:component-scan base-package="com.shaun" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
这里在spring-mvc.xml中只扫描@controller,在spring-context.xml中不扫描controller,这样做是因为我们的事物配置是配置在spring主容器也就是spring-context.xml中,如果我们通过springmvc扫描@service,那么将出现事物配置失效的问题。如果我们将controller配置在Spring-context.xml中,那么我们的controller访问将出现404的情况。Spring和springmvc父子容器注解扫描问题详解
主容器中扫描路径配置
<context:component-scan base-package="com.shaun">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
有了这两个xml,我们再在web项目描述文件中配置ContextConfigLocation和DispatcherServlet
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring-context.xmlparam-value>
context-param>
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
spring-mvc.xml中配置视图解析器
id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/">property>
<property name="suffix" value=".jsp">property>
接下来配置数据源,使用mysql数据库。新建spring-datasource.xml,并将该文件引入spring-contex.xml中
<import resource="classpath:spring/spring-datasource.xml"/>
数据源使用commons-dbcp的包,mysql的驱动包。配置如下
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>${jdbc.driver}value>
property>
<property name="url">
<value>${jdbc.url}value>
property>
<property name="username">
<value>${jdbc.username}value>
property>
<property name="password">
<value>${jdbc.password}value>
property>
<property name="maxActive">
<value>${jdbc.maxActive}value>
property>
<property name="maxWait">
<value>${jdbc.maxWait}value>
property>
<property name="maxIdle">
<value>${jdbc.maxIdle}value>
property>
bean>
jdbc.properties文件如下
#驱动包
jdbc.driver=com.mysql.jdbc.Driver
#mysqlUrl
jdbc.url=jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
#最大并发连接数
jdbc.maxActive=255
#最大等待时间
jdbc.maxWait=12000
#最大空闲连接数
jdbc.maxIdle=2
接下来配置数据源的事物代理。新建spring-transaction.xml并引入spring-context.xml中。
<import resource="classpath:spring/spring-transaction.xml"/>
<bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<property name="targetDataSource" ref="datasource"/>
bean>
<bean id="dataSourceProxyTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceProxy"/>
bean>
<bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
lazy-init="false" abstract="true">
<property name="transactionManager" ref="dataSourceProxyTransactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED,-AppException,-PrcException,-IllegalArgumentExceptionprop>
props>
property>
bean>
AppException为自定义抛出的异常。
接下来配置Ibatis。新建spring-ibatis.xml并引入spring-context.xml中
<import resource="classpath:spring/spring-ibatis.xml"/>
ibatis的使用,通过SqlMapClientBuilder创建sqlMapClient对象,调用封装的方法。
String conf = "ibatis/IbatisSqlMapConfig.xml";
try{
Reader reader = Resources.getResourceAsReader(conf);
SqlMapClient sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
// List list = sqlMapClient.queryForList("leaderI.selectLeader");
List list = sqlMapClient.queryForList("lock.getAllLocks");
在spring里,SqlMapClientFactoryBean创建SqlMapClient bean实例,配置如下
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocations">
<list>
<value>classpath:ibatis/spring-ibatis-cfg.xmlvalue>
list>
property>
<property name="dataSource">
<ref bean="dataSourceProxy"/>
property>
bean>
创建sqlExcutor,sqlMapClientTemplate bean实例
id="sqlExcutor" class="com.ibatis.sqlmap.engine.execution.SqlExecutor"/>
id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient" ref="sqlMapClient"/>
创建Dao对象,IDao.java代码如下
package com.shaun.commons.dao;
import com.ibatis.sqlmap.client.SqlMapExecutor;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
/**
* @Author
* @Description
* @Date Created on 2017/9/6.
*/
public class IDao{
public SqlMapClientTemplate sqlMapClientTemplate;
public SqlMapClientTemplate getSqlMapClientTemplate() {
return sqlMapClientTemplate;
}
public void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) {
this.sqlMapClientTemplate = sqlMapClientTemplate;
}
public int delete(String statementName) throws DataAccessException {
return this.getSqlMapClientTemplate().delete(statementName);
}
public int delete(String statementName, Object obj) throws DataAccessException{
return this.getSqlMapClientTemplate().delete(statementName, obj);
}
public Object insert(String statementName) throws DataAccessException{
return this.getSqlMapClientTemplate().insert(statementName);
}
public Object insert(String statementName, Object obj) throws DataAccessException{
return this.getSqlMapClientTemplate().insert(statementName,obj);
}
public int update(String statementName) throws DataAccessException{
return this.getSqlMapClientTemplate().update(statementName);
}
public int update(String statementName, Object obj) throws DataAccessException{
return this.getSqlMapClientTemplate().update(statementName,obj);
}
public Object queryForObject(String statementName) throws DataAccessException{
return this.getSqlMapClientTemplate().queryForObject(statementName);
}
public Object queryForObject(String statementName, Object obj) throws DataAccessException{
return this.getSqlMapClientTemplate().queryForObject(statementName,obj);
}
public List queryForList(String statementName) throws DataAccessException{
return this.getSqlMapClientTemplate().queryForList(statementName);
}
public List queryForList(String statementName, Object obj) throws DataAccessException{
return this.getSqlMapClientTemplate().queryForList(statementName, obj);
}
public List queryForPage(String var1, Object var2, int var3, int var4){
return this.getSqlMapClientTemplate().queryForList(var1, var2, var3, var4);
}
public SqlMapClientTemplate getSqlMapClientTemplateTemplate(){
return this.getSqlMapClientTemplate();
}
public int insertBatch(final String statementName,final List list) throws DataAccessException{
this.getSqlMapClientTemplate().execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
executor.startBatch();
Iterator var2 = list.iterator();
while(var2.hasNext()) {
Object object = var2.next();
executor.insert(statementName, object);
}
executor.executeBatch();
return null;
}
});
return list.size();
}
}
将sqlMapClientTemplate bean实例注入到IDao的SqlMapClientTemplate属性,通过setter方法注入
id="baseDao" class="com.shaun.commons.dao.IDao">
<property name="SqlMapClientTemplate">
<ref bean="sqlMapClientTemplate"/>
property>
创建所有Service父类BaseDaoServiceImpl.java
import com.shaun.commons.dao.IDao;
/**
* @Author
* @Description
* @Date Created on 2017/9/6.
*/
public class BaseDaoServiceImpl{
private IDao appDao;
public IDao getAppDao() {
return appDao;
}
public void setAppDao(IDao appDao) {
this.appDao = appDao;
}
}
将父类service配置到容器中
id="baseDaoService" class="com.shaun.commons.service.impl.BaseDaoServiceImpl">
<property name="appDao">
<ref bean="baseDao"/>
property>
编写service 例如LoginService,service继承父类service,可以调用dao的方法,同时service通过targetSource进行了事物管理
<bean id="loginService" parent="transactionProxy">
<property name="target">
<bean class="com.shaun.login.service.impl.LoginServiceImpl" parent="baseDaoService">
bean>
property>
bean>
package com.shaun.login.service.impl;
import com.shaun.commons.dao.IDao;
import com.shaun.commons.service.impl.BaseDaoServiceImpl;
import com.shaun.login.service.LoginService;
import java.util.Map;
/**
* @Author
* @Description
* @Date Created on 2017/9/6.
*/
public class LoginServiceImpl extends BaseDaoServiceImpl implements LoginService {
@Override
public Map queryByUserName(String userName){
IDao iDao = super.getAppDao();
return (Map)iDao.queryForObject("login.queryByUserName",userName);
}
}
这里笔者犯了一个错误,在controller中使用注解方式获取Service,发现启动时容器报错,Spring没有定义这个bean。改用ApplicationContext能获取bean。问题出在哪儿呢?
//自动注入失败
@Autowired
LoginService loginService;
//手动获取bean成功
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-context.xml");
LoginService loginService = (LoginService)ac.getBean("loginService");
问题出在哪儿呢?笔者于是封装了Controller父类,BaseController
public class BaseController {
public Object getService(String serviceName){
WebApplicationContext wc = ContextLoader.getCurrentWebApplicationContext();
return wc.getBean(serviceName);
}
@Autowired
protected HttpServletRequest request;
}
LoginController中获取Service改用父类定义的方法获取。
LoginService loginService = (LoginService) super.getService("loginService");
这时启动容器发现异常信息NullPointerException,发现问题所在,原来是容器启动时没有装配spring的配置,在web.xml中配置监听器ContextLoaderListener。
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
首先引入spring-security的jar包。创建spring-security.xml并引入spring-contex.xml文件中。这里使用的命名空间是b:beans
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<http pattern="/resources/**" security="none"/>
<http pattern="/login.jsp" security="none"/>
<http pattern="/checkUser.do" security="none"/>
<http pattern="/loginAction.do" security="none"/>
<http use-expressions="true" entry-point-ref="myAuthenticationEntryPoint">
<intercept-url pattern="/**" access="isAuthenticated()"/>
<csrf disabled="true"/>
<custom-filter ref="myAuthenticationFilter" position="FORM_LOGIN_FILTER" />
http>
<b:bean id="myAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<b:constructor-arg name="loginFormUrl" value="/login.jsp">b:constructor-arg>
b:bean>
<b:bean id="myAuthenticationFilter" class="com.shaun.commons.filter.MyAuthenticationFilter">
<b:property name="authenticationManager" ref="authenticationManager" />
<b:property name="filterProcessesUrl" value="/j_spring_security_check" />
<b:property name="authenticationSuccessHandler">
<b:bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<b:property name="defaultTargetUrl" value="/indexAction.do" />
b:bean>
b:property>
<b:property name="authenticationFailureHandler">
<b:bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<b:property name="defaultFailureUrl" value="/accessDenied.jsp" />
b:bean>
b:property>
b:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="MyUserDetailsService">
<password-encoder ref="md5Encoder">password-encoder>
authentication-provider>
authentication-manager>
<b:bean id="md5Encoder" class="com.shaun.commons.util.Md5SecurityPasswordEncoder">b:bean>
<b:bean id="MyUserDetailsService" parent="transactionProxy">
<b:property name="target">
<b:bean class="com.shaun.commons.service.impl.MyUserDetailServiceImpl"
parent="baseDaoService">b:bean>
b:property>
b:bean>
<b:bean id="myAccessDecisionManagerBean"
class="com.shaun.commons.filter.MyAccessDecisionManager"/>
<b:bean id="securityMetadataSource"
class="com.shaun.commons.filter.MyInvocationSecurityMetadataSource" />
b:beans>
在web.xml中配置过滤器DelegatingFilterProxy
<filter>
<filter-name>springSecurityFilterChainfilter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
filter>
这里笔者重写了认证过滤器myAuthenticationFilter,如果不重写,会使用UsernamePasswordAuthenticationFilter处理。在过滤器中可以加入验证码的验证等。
package com.shaun.commons.filter;
import com.shaun.commons.entity.MyUser;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Author
* @Description
* @Date Created on 2017/9/11.
*/
public class MyAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
Authentication authentication = super.attemptAuthentication(request, response);
MyUser user = (MyUser) authentication.getPrincipal();
request.getSession().setAttribute("userName",user.getUsername());
return authentication;
}
@Override
protected String obtainPassword(HttpServletRequest request) {
return super.obtainPassword(request);
}
@Override
protected String obtainUsername(HttpServletRequest request) {
return super.obtainUsername(request);
}
@Override
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
super.setDetails(request, authRequest);
}
}
为了使用自定义数据库,配置authentication-manager时使用自定义的UserDetailsService,重写loadUserByUsername方法
package com.shaun.commons.service.impl;
import com.shaun.commons.dao.IDao;
import com.shaun.commons.entity.AppRole;
import com.shaun.commons.entity.MyUser;
import com.shaun.commons.util.AppException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @Author
* @Description
* @Date Created on 2017/9/8.
*/
public class MyUserDetailServiceImpl extends BaseDaoServiceImpl implements UserDetailsService {
public MyUserDetailServiceImpl(){
}
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
Map resMap = (Map)this.getAppDao().queryForObject("login.queryByUserName",s);
if(resMap.isEmpty()){
throw new UsernameNotFoundException("没有找到用户信息");
}else {
MyUser user = new MyUser();
user.setUserName(resMap.get("username")+"");
user.setPassword(resMap.get("password")+"");
AppRole appRole = new AppRole();
appRole.setRoleName(AppRole.ROLE_USER);
Set set = new HashSet();
set.add(appRole);
user.setRoles(set);
return user;
}
}
}
AppRole继承了GrantedAuthority类
package com.shaun.commons.entity;
import org.springframework.security.core.GrantedAuthority;
/**
* @Author
* @Description
* @Date Created on 2017/9/8.
*/
public class AppRole implements GrantedAuthority{
public static String ROLE_USER = "ROLE_USER";
private String roleName;
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
@Override
public String getAuthority() {
return this.roleName;
}
}
使用加密算法
package com.shaun.commons.util;
import org.springframework.security.authentication.encoding.PasswordEncoder;
/**
* @Author
* @Description
* @Date Created on 2017/9/11.
*/
public class Md5SecurityPasswordEncoder implements PasswordEncoder{
@Override
public String encodePassword(String rawPass, Object salt) {
if ("userNotFoundPassword".equals(rawPass)) {
return "";
} else {
return Md5EncodeUtil.md5Encode(rawPass);
}
}
@Override
public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
return encPass.equals(this.encodePassword(rawPass, salt));
}
}
package com.shaun.commons.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @Author
* @Description
* @Date Created on 2017/9/8.
*/
public class Md5EncodeUtil {
public static Md5EncodeUtil instance;
private static Log log = LogFactory.getLog(Md5EncodeUtil.class);
static {
instance = new Md5EncodeUtil();
}
public static Md5EncodeUtil getInstance(){
return instance;
}
public static String md5Encode(String str){
String beforeEncodeStr = str+"-a1b2";//偏移码(salt)-a1b2
try{
MessageDigest md5 = MessageDigest.getInstance("MD5");
BASE64Encoder base64Encoder = new BASE64Encoder();
String encodedStr = base64Encoder.encode(md5.digest(beforeEncodeStr.getBytes("UTF-8")));
return encodedStr;
}catch (NoSuchAlgorithmException e){
log.error(e);
return null;
}catch (UnsupportedEncodingException e){
log.error(e);
return null;
}
}
}