SpringMVC+Ibatis+SPring Security开发框架搭建

来源:互联网 发布:手机淘宝已购买生成器 编辑:程序博客网 时间:2024/05/16 19:04

近期做一个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.0</modelVersion>  <groupId>com.xz</groupId>  <artifactId>mavenDemo</artifactId>  <packaging>pom</packaging>  <version>1.0-SNAPSHOT</version>  <properties>    <spring.version>4.3.7.RELEASE</spring.version>    <mysql.version>5.1.7</mysql.version>    <conmons-lang.version>2.4</conmons-lang.version>    <servlet-api.version>2.4</servlet-api.version>    <jsp-api>2.1</jsp-api>  </properties>  <modules>    <module>security</module>  </modules>  <name>security Maven Webapp</name>  <url>http://maven.apache.org</url>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>test</scope>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-core</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-web</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-beans</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-webmvc</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-context</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-jdbc</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-tx</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-orm</artifactId>      <version>3.2.7.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-context-support</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-aop</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>com.mysql</groupId>      <artifactId>mysql-connector-java</artifactId>      <version>${mysql.version}</version>    </dependency>    <!--apache的连接池jar包-->    <dependency>      <groupId>commons-dbcp</groupId>      <artifactId>commons-dbcp</artifactId>      <version>1.4</version>    </dependency>    <dependency>      <groupId>commons-lang</groupId>      <artifactId>commons-lang</artifactId>      <version>${conmons-lang.version}</version>    </dependency>    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>servlet-api</artifactId>      <version>${servlet-api.version}</version>    </dependency>    <dependency>      <groupId>javax.servlet.jsp</groupId>      <artifactId>jsp-api</artifactId>      <version>${jsp-api}</version>    </dependency>    <dependency>      <groupId>commons-logging</groupId>      <artifactId>commons-logging</artifactId>      <version>1.2</version>    </dependency>    <!--阿里巴巴的连接池jar包-->    <dependency>      <groupId>com.alibaba</groupId>      <artifactId>druid</artifactId>      <version>1.0.17</version>    </dependency>    <dependency>      <groupId>com.yinhai</groupId>      <artifactId>ibatis</artifactId>      <version>2.0</version>    </dependency>    <dependency>      <groupId>log4j</groupId>      <artifactId>log4j</artifactId>      <version>1.2.17</version>    </dependency>    <dependency>      <groupId>org.slf4j</groupId>      <artifactId>slf4j-api</artifactId>      <version>1.7.12</version>    </dependency>    <dependency>      <groupId>org.slf4j</groupId>      <artifactId>slf4j-log4j12</artifactId>      <version>1.7.12</version>    </dependency>    <dependency>      <groupId>commons-logging</groupId>      <artifactId>commons-logging</artifactId>      <version>1.2</version>    </dependency>  </dependencies>  <build>    <finalName>security</finalName>    <plugins>      <!--配置编译java文件的插件-->      <plugin>        <artifactId>maven-compiler-plugin</artifactId>        <version>2.3.2</version>        <configuration>          <source>1.7</source>          <target>1.7</target>          <encoding>UTF-8</encoding>        </configuration>      </plugin>      <!--配置maven调用测试方法的插件-->      <plugin>        <artifactId>maven-surefire-plugin</artifactId>        <version>2.7</version>        <configuration>          <skipTests>true</skipTests><!--跳过测试-->          <testFailureIgnore>true</testFailureIgnore><!--忽略测试失败-->        </configuration>      </plugin>      <!--maven版本java版本约束-->      <plugin>        <artifactId>maven-enforcer-plugin</artifactId>        <version>1.1</version>        <executions>          <execution>            <id>enforce-tools</id>            <goals>              <goal>enforce</goal>            </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>mavenDemo</artifactId>        <groupId>com.xz</groupId>        <version>1.0-SNAPSHOT</version>    </parent>    <modelVersion>4.0.0</modelVersion>    <artifactId>security</artifactId>    <packaging>war</packaging>    <name>security Maven Webapp</name>    <url>http://maven.apache.org</url>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>3.8.1</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>            <version>1.2.28</version>        </dependency>        <dependency>            <groupId>org.springframework.security</groupId>            <artifactId>spring-security-config</artifactId>            <version>4.0.4.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework.security</groupId>            <artifactId>spring-security-core</artifactId>            <version>4.0.4.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework.security</groupId>            <artifactId>spring-security-taglibs</artifactId>            <version>4.0.4.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework.security</groupId>            <artifactId>spring-security-web</artifactId>            <version>4.0.4.RELEASE</version>        </dependency>        <dependency>            <groupId>org.springframework.security</groupId>            <artifactId>spring-security-acl</artifactId>            <version>4.0.4.RELEASE</version>        </dependency>    </dependencies>    <build>        <finalName>security</finalName>    </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.properties</value>                <value>classpath:jdbc.properties</value>            </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父子容器注解扫描问题详解
主容器中扫描路径配置

<!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。  -->    <context:component-scan base-package="com.shaun"><!-- base-package 如果多个,用“,”分隔 -->        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>    </context:component-scan>

有了这两个xml,我们再在web项目描述文件中配置ContextConfigLocation和DispatcherServlet

<!--通过contextConfigLocation加载spring总配置文件-->  <context-param>    <param-name>contextConfigLocation</param-name>    <param-value>classpath:spring-context.xml</param-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中配置视图解析器

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/WEB-INF/page/"></property>        <property name="suffix" value=".jsp"></property>    </bean>

接下来配置数据源,使用mysql数据库。新建spring-datasource.xml,并将该文件引入spring-contex.xml中

<!--引入datasource文件--><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#mysqlUrljdbc.url=jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf-8jdbc.username=rootjdbc.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">    <!--将数据源bean交给DataSourceProxy代理-->    <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,-IllegalArgumentException</prop>            </props>    </property></bean>

AppException为自定义抛出的异常。

Ibatis的配置

接下来配置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.xml</value>        </list>    </property>    <property name="dataSource">        <ref bean="dataSourceProxy"/>    </property></bean>

创建sqlExcutor,sqlMapClientTemplate bean实例

<bean id="sqlExcutor" class="com.ibatis.sqlmap.engine.execution.SqlExecutor"/><bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">        <property name="sqlMapClient" ref="sqlMapClient"/></bean>

创建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方法注入

<bean id="baseDao" class="com.shaun.commons.dao.IDao">        <property name="SqlMapClientTemplate">            <ref bean="sqlMapClientTemplate"/>        </property></bean>

创建所有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配置到容器中

<bean id="baseDaoService" class="com.shaun.commons.service.impl.BaseDaoServiceImpl">    <property name="appDao">         <ref bean="baseDao"/>    </property></bean>

编写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。问题出在哪儿呢?

//自动注入失败@AutowiredLoginService 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.ContextLoaderListener</listener-class>  </listener>

spring-sercurity的配置

首先引入spring-security的jar包。创建spring-security.xml并引入spring-contex.xml文件中。这里使用的命名空间是b:beans

<?xml version="1.0" encoding="UTF-8"?><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>springSecurityFilterChain</filter-name>    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-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;        }    }}
原创粉丝点击