spring security+mybatis+springMVC构建一个简单的项目
1.引用

4 ).实际项目中会采用maven进行jar包的管理,此项目我们也采用maven来管理项目
项目我也上传了 ,若是需要可以搜索spring security+mybatis+springMVC 关键字 寻找资源
spring security ,这是一种基于spring AOP和Servlet的过滤安全框架。它提供全面的安全性解决方案,同时在web请求级和方法的调用级处理身份确认和授权。在spring framework基础上,spring security充分利用了依赖注入(DI,Dependency Injection)和AOP技术。
下面就让我们用一个小的晓得项目来出初步了解Spring Security 的强大功能吧。
2.项目实战
1)项目的技术架构:maven+spring security+springmvc+mybatis。
当然后面还会有持久层采用hibernate框架的。话说得再多,还不如做一个项目来的实在,下面就让我们开始我们的项目吧。本项目涉及到的知识点可能比较多,对基础的要求比较高,请谨慎阅读。
项目部分:
1)项目结构图:
2)web.xml文件,它是所有web项目的入口文件,我们就从它开始下手吧。
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"><display-name>mybatis</display-name><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring.xml,classpath:spring-mybatis.xml,classpath:spring-security.xml</param-value></context-param><servlet><description>spring mvc servlet</description><servlet-name>springMvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><description>spring mvc 配置文件</description><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springMvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping><filter><filter-name>springSecurityFilterChain</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>springSecurityFilterChain</filter-name><url-pattern>/*</url-pattern></filter-mapping><filter><description>字符集过滤器</description><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><description>字符集编码</description><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 配置session监听器 --><listener><description>session监听器</description><listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class></listener><listener><description>spring监听器</description><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><listener><listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class></listener><context-param><param-name>spring.profiles.active</param-name><param-value>dev</param-value></context-param><context-param><param-name>spring.profiles.default</param-name><param-value>dev</param-value></context-param><context-param><param-name>spring.liveBeansView.mbeanDomain</param-name><param-value>dev</param-value></context-param><welcome-file-list><welcome-file>/index.jsp</welcome-file></welcome-file-list><session-config><session-timeout>15</session-timeout></session-config></web-app>
3).我们的项目要尽量的贴合实际项目,所以项目中我也整合了数据库,因为大部分应用中mysql用得比较多,我就用mysql做吧
drop table if exists sec_user;create table sec_user(id int(11) primary key auto_increment,username varchar(50),password varchar(50),role varchar(50),access int(10))enging=inno_db default charset=utf8;
4 ).实际项目中会采用maven进行jar包的管理,此项目我们也采用maven来管理项目
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"><modelVersion>4.0.0</modelVersion><groupId>mybatis_security_session</groupId><artifactId>mybatis_security_session</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>springsecurity Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>3.2.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>3.2.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>3.2.0.RELEASE</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>3.2.0.RELEASE</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-taglibs</artifactId><version>3.2.0.RELEASE</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.1.1</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.2.2</version></dependency><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.21</version></dependency><dependency><groupId>org.apache.struts</groupId><artifactId>struts2-dojo-plugin</artifactId><version>2.3.24.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.7.1</version></dependency><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-mapper-asl</artifactId><version>1.9.11</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.2.2</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>3.0-alpha-1</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!--alibaba 数据源jar 来刮泥数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>0.2.9</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.1.26</version></dependency></dependencies><build></build></project>
5)实体部分
a.实体类文件 user.java
package sy.model;import java.io.Serializable;public class User implements Serializable{private static final long serialVersionUID = 1L;private Integer id;private String username;private String password;private String role;private int access;public int getAccess() {return access;}public void setAccess(int access) {this.access = access;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username == null ? null : username.trim();}public String getPassword() {return password;}public void setPassword(String password) {this.password = password == null ? null : password.trim();}public String getRole() {return role;}public void setRole(String role) {this.role = role == null ? null : role.trim();}}
b.user的映射文件,写得比较简单。
UserMapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><mapper namespace="sy.dao.UserMapper" ><resultMap id="BaseResultMap" type="sy.model.User" ><id column="id" property="id" jdbcType="INTEGER" /><result column="username" property="username" jdbcType="VARCHAR" /><result column="password" property="password" jdbcType="VARCHAR" /><result column="role" property="role" jdbcType="VARCHAR" /><result column="access" property="access" jdbcType="INTEGER" /></resultMap><sql id="Base_Column_List" >id, username, password, role,access</sql><select id="selectByUserName" resultMap="BaseResultMap" parameterType="java.lang.Integer" >select<include refid="Base_Column_List" />from sec_userwhere username = #{username,jdbcType=VARCHAR}</select><select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer">select<include refid="Base_Column_List"/>from sec_userwhere id = #{id,jdbcType=INTEGER}</select></mapper>
6)dao层,业务数据处理层。因为采用的是mybatis框架,所以dao层会特别的简单,这也侧面的体现了mybatis的强大。
UserMaper.java文件
package sy.dao;import sy.model.User;public interface UserMapper {User selectByUserName(String username);User selectByPrimaryKey(Integer id);}
7)要写配置文件了,这是个比较重要的部分,当然也特别的基础。以下会有多个配置文件,而且没有配置文件功能都细分的的很明确。
a , config.properties文件:存放数据库连接时必须用到的信息
#hibernate.dialect=org.hibernate.dialect.OracleDialect#driverClassName=oracle.jdbc.driver.OracleDriver#validationQuery=SELECT 1 FROM DUAL#jdbc_url=jdbc:oracle:thin:@localhost:1521:orcl#jdbc_username=sypro#jdbc_password=syprohibernate.dialect=org.hibernate.dialect.MySQLDialectdriverClassName=com.mysql.jdbc.DrivervalidationQuery=SELECT 1jdbc_url=jdbc:mysql://localhost:3306/sy?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=truejdbc_username=rootjdbc_password=1234#hibernate.dialect=org.hibernate.dialect.SQLServerDialect#driverClassName=net.sourceforge.jtds.jdbc.Driver#validationQuery=SELECT 1#jdbc_url=jdbc:jtds:sqlserver://127.0.0.1:1433/sy#jdbc_username=sa#jdbc_password=123456#hibernate.dialect=org.hibernate.dialect.DerbyDialect#driverClassName=org.apache.derby.jdbc.EmbeddedDriver#validationQuery=SELECT 1#jdbc_url=jdbc:derby:sy;create=true#jdbc_username=sypro#jdbc_password=sypro#jndiName=java:comp/env/dataSourceName#hibernate.hbm2ddl.auto=update#hibernate.show_sql=false#hibernate.format_sql=truesessionInfoName=sessionInfouploadFieldName=filedatauploadFileMaxSize=20971520uploadFileExts=txt,rar,zip,doc,docx,xls,xlsx,jpg,jpeg,gif,png,swf,wmv,avi,wma,mp3,miduploadDirectory=attached
b,log4j文件配置,里面的信息不做详细说明。
log4j.properties文件
log4j.rootLogger=DEBUG,Console,Filelog4j.appender.Console=org.apache.log4j.ConsoleAppenderlog4j.appender.Console.Target=System.outlog4j.appender.Console.layout=org.apache.log4j.PatternLayoutlog4j.appender.Console.layout.ConversionPattern=[%c]%m%nlog4j.appender.File=org.apache.log4j.RollingFileAppenderlog4j.appender.File.File=mybatis.loglog4j.appender.File.MaxFileSize=10MBlog4j.appender.File.Threshold=ALLlog4j.appender.File.layout=org.apache.log4j.PatternLayoutlog4j.appender.File.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c]%m%n
c,以下的配置文件会比较重要。
spring.xml文件,存放通用的逻辑 :获取配置文件比如像properties类的文件
扫面项目的包
开启各个注解功能
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd"><!-- 引入属性文件 --><context:property-placeholder location="classpath:config.properties" /><!-- 自动扫描(自动注入) --><context:component-scan base-package="sy" /><context:annotation-config /><!--jass config --><bean id="jaasAuthenticationProvider"class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider"><property name="loginConfig" value="/WEB-INF/login.conf" /><property name="loginContextName" value="JAASTest" /><property name="callbackHandlers"><list><beanclass="org.springframework.security.authentication.jaas.JaasNameCallbackHandler" /><beanclass="org.springframework.security.authentication.jaas.JaasPasswordCallbackHandler" /></list></property><property name="authorityGranters"><list><beanclass="sy.service.AuthorityGranterImpl" /></list></property></bean></beans>
d, mybatis的配置文件
spring-mybatis.xml文件。此部分配置了与数据源有关的东西:sessionFactory
spring事务控制AOP
采用的阿里巴巴的数据源jar包作业。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd"><!-- JNDI方式配置数据源 --><!-- <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="${jndiName}"></property> </bean> --><!-- 配置数据源 --><bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><!--数据源驱动类可以不用写,Druid默认会自动根据URL识别DriverClass --><!-- <property name="driverClassName" value="com.mysql.jdbc.Driver"/> --><property name="url" value="${jdbc_url}" /><property name="username" value="${jdbc_username}" /><property name="password" value="${jdbc_password}" /><!-- 初始化连接大小 --><property name="initialSize" value="0" /><!-- 连接池最大使用连接数量 --><property name="maxActive" value="20" /><!-- 连接池最大空闲 --><property name="maxIdle" value="20" /><!-- 连接池最小空闲 --><property name="minIdle" value="0" /><!-- 获取连接最大等待时间 --><property name="maxWait" value="60000" /><!-- <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="33" /> --><property name="validationQuery" value="${validationQuery}" /><property name="testOnBorrow" value="false" /><property name="testOnReturn" value="false" /><property name="testWhileIdle" value="true" /><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --><property name="timeBetweenEvictionRunsMillis" value="60000" /><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --><property name="minEvictableIdleTimeMillis" value="25200000" /><!-- 打开removeAbandoned功能 --><property name="removeAbandoned" value="true" /><!-- 1800秒,也就是30分钟 --><property name="removeAbandonedTimeout" value="1800" /><!-- 关闭abanded连接时输出错误日志 --><property name="logAbandoned" value="true" /><!--配置监控统计拦截 监控数据库 --><!-- <property name="filters" value="stat" /> --><property name="filters" value="mergeStat" /></bean><!-- 配置SqlsessionFactoryBean myBatis文件--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><!-- 自动扫描entity目录, 省掉Configuration.xml里的手工配置 --><property name="mapperLocations" value="classpath:sy/mapping/*.xml" /></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="sy.dao" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /></bean><!-- 配置事务管理器 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!-- 注解方式配置事物 --><!-- <tx:annotation-driven transaction-manager="transactionManager" /> --><!-- 拦截器方式配置事物 --><tx:advice id="transactionAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="add*" propagation="REQUIRED" /><tx:method name="append*" propagation="REQUIRED" /><tx:method name="insert*" propagation="REQUIRED" /><tx:method name="save*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="modify*" propagation="REQUIRED" /><tx:method name="edit*" propagation="REQUIRED" /><tx:method name="delete*" propagation="REQUIRED" /><tx:method name="remove*" propagation="REQUIRED" /><tx:method name="repair" propagation="REQUIRED" /><tx:method name="delAndRepair" propagation="REQUIRED" /><tx:method name="get*" propagation="SUPPORTS" /><tx:method name="find*" propagation="SUPPORTS" /><tx:method name="load*" propagation="SUPPORTS" /><tx:method name="search*" propagation="SUPPORTS" /><tx:method name="datagrid*" propagation="SUPPORTS" /><tx:method name="*" propagation="SUPPORTS" /></tx:attributes></tx:advice><aop:config><aop:pointcut id="transactionPointcut" expression="execution(* sy.service..*Impl.*(..))" /><aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" /></aop:config><!-- 配置druid监控spring jdbc --><bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor"></bean><bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype"><property name="patterns"><list><value>sy.service.*</value></list></property></bean><aop:config><aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" /></aop:config></beans>
e,我们比较熟悉的部分了springMVC的配置文件,说是控制层的配置文件也是很有道理的
spring-mvc.xml文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"><!-- 自动扫描controller包下的所有类,使其认为spring mvc的控制器 --><context:component-scan base-package="sy.controller" /><!-- 避免IE执行AJAX时,返回JSON出现下载文件 --><bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=UTF-8</value></list></property></bean><!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --><bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"><property name="messageConverters"><list><ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 --></list></property></bean><!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 --><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/views/" p:suffix=".jsp" /><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="defaultEncoding"><value>UTF-8</value></property><property name="maxUploadSize"><value>32505856</value><!-- 上传文件大小限制为31M,31*1024*1024 --></property><property name="maxInMemorySize"><value>4096</value></property></bean></beans>
f,这文件应该是我们最关注的spring-security.xml文件,这文件可能没有多少注解,我希望大家能去网上多看看文档,这样记忆文比较深刻,我写出来没有多少意义,因为这个文件是spring security的关键。
<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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security-3.2.xsd"><http auto-config="true" use-expressions="true"access-denied-page="/auth/denied"> <!-- 拒绝被方访问时转向改页面 --><intercept-url pattern="/auth/login" access="permitAll" /><intercept-url pattern="/main/admin" access="hasRole(‘ROLE_ADMIN‘)" /><intercept-url pattern="/main/common" access="hasRole(‘ROLE_USER‘)" /><form-login login-page="/auth/login"authentication-failure-url="/auth/login?error=true"default-target-url="/main/common" /><logout invalidate-session="true" logout-success-url="/auth/login"logout-url="/auth/logout" /><session-management><concurrency-control max-sessions="1"error-if-maximum-exceeded="true" expired-url= "/auth/login?error=expired" /></session-management><!--退出登录是删除对应的session 信息 --><logout delete-cookies="JSESSIONID"/><http-basic /></http><!-- 方法级别的权限控制,需要用这个注解标签来开启--><global-method-security jsr250-annotations="enabled" /><authentication-manager><!--这里必须用ref来连接 不能用user-service-ref 来连接 ,它是用来连接userDetailsService接口的实现的 --><authentication-provider ref="jaasAuthenticationProvider" /></authentication-manager></beans:beans>
好了到此配置文件就完成了,下面将是项目的核心部分了,当然spring security也在里面,jsp文件我将贴在最后面。
核心代码块:
控制层(controller):
LoginLoginoutController.java文件
package sy.controller;import org.apache.log4j.Logger;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;@Controller@RequestMapping("auth")public class LoginLogoutController {protected static Logger logger = Logger.getLogger("controller");/*** 指向登录页面*/@RequestMapping(value = "/login", method = RequestMethod.GET)public String getLoginPage(@RequestParam(value = "error", required = false) boolean error,ModelMap model) {logger.debug("Received request to show login page");if (error == true) {// Assign an error messagemodel.put("error","You have entered an invalid username or password!");} else {model.put("error", "");}return "loginpage";}/*** 指定无访问额权限页面** @return*/@RequestMapping(value = "/denied", method = RequestMethod.GET)public String getDeniedPage() {logger.debug("Received request to show denied page");return "deniedpage";}}
MainController.java文件
package sy.controller;import org.apache.log4j.Logger;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import sy.model.User;import sy.service.UserServiceI;@Controller@RequestMapping("/main")public class MainController {protected static Logger logger = Logger.getLogger("controller");private UserServiceI sevice;@Autowiredpublic void setSevice(UserServiceI sevice) {this.sevice = sevice;}/*** 跳转到commonpage页面** @return*/@RequestMapping(value = "/common", method = RequestMethod.GET)public String getCommonPage() {//这里是为spring security在方法级别的控制而准备的,getUserByPrimary方法,需要RELE_ADMIN权限User user = sevice.getUserByPrimaryKey(1);System.err.println("---------"+user.getUsername());logger.debug("Received request to show common page");return "commonpage";}/*** 跳转到adminpage页面** @return*/@RequestMapping(value = "/admin", method = RequestMethod.GET)public String getAadminPage() {logger.debug("Received request to show admin page");return "adminpage";}}
UserDetails接口的实现,这个接口是为UserDetailsService服务的,当然我们做的这个项目使用jaas认证来写,这个类用不到,提到了就给大家贴出来。
JAAS的定义:Java Authentication Service(JAAS,Java验证和授权)提供灵活可伸缩的的机制来保护客户端或服务器端的java程序。JAAS强调的是通过验证谁在运行代码以及他/她的权限来保护系统免受用户的攻击。它让你能够将一些标准的安全机制,列如Solaris,NIS(网络信息服务),Windsow NT,LDAP(轻量目录存取协议),Kerberos等通过一种通用的,可以配置的方式集成到系统中去。
UserLoginDetails.java文件
package sy.security;import java.util.Collection;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;public class UserLoginDetails implements UserDetails{private static final long serialVersionUID = 1L;private String username;private String password;private boolean enabled;private Collection<? extends GrantedAuthority> authorities;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public void setEnabled(boolean enabled) {this.enabled = enabled;}public Collection<? extends GrantedAuthority> getAuthorities() {return authorities;}public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {this.authorities = authorities;}public boolean isAccountNonExpired() {return enabled;}public boolean isAccountNonLocked() {return enabled;}public boolean isCredentialsNonExpired() {return enabled;}public boolean isEnabled() {return enabled;}}
sevice层,数据业务核心层
UserServiceI.java文件,这里我们又可以感受一下mybatis的强大了,是不是太简单了
package sy.service;import sy.model.User;import javax.annotation.security.RolesAllowed;public interface UserServiceI {User getUserByUserName(String username);//spring security方法级别的控制,使用该方法需要的权限@RolesAllowed("ROLE_ADMIN")User getUserByPrimaryKey(Integer id);}
UserServiceImpl.java
package sy.service;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import sy.dao.UserMapper;import sy.model.User;@Service("userService")public class UserServiceImpl implements UserServiceI {private UserMapper userMapper;public UserMapper getUserMapper() {return userMapper;}@Autowiredpublic void setUserMapper(UserMapper userMapper) {this.userMapper = userMapper;}public User getUserByUserName(String username) {System.err.println("find by name !");return userMapper.selectByUserName(username);}public User getUserByPrimaryKey(Integer id) {return userMapper.selectByPrimaryKey(id);}}
Jaas核心代码块;
jass必须实现这两接口
AuthorityGranter 做权限的赋予
LoginModule 做登录的验证
AuthorityGranter接口的实现类 AuthorityGranterImpl.java
package sy.service;import java.security.Principal;import java.util.Set;import javax.annotation.Resource;import java.util.HashSet;import org.springframework.security.authentication.jaas.AuthorityGranter;import sy.model.User;public class AuthorityGranterImpl implements AuthorityGranter{@Resourceprivate UserServiceI serviceI;public Set<String> grant(Principal principal) {String name = principal.getName();System.err.println("DefaultAuthorutyGranter Principal : "+name);User user = serviceI.getUserByUserName(name);String [] roles = user.getRole().split(",");Set<String> authoritys = new HashSet<String>();for(String role:roles){authoritys.add(role);}//return Collections.singleton("ROLE_USER");return authoritys;}}
LoginModule接口的实现类LoginModuleImpl.java
package sy.service;import java.io.IOException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Map;import javax.security.auth.Subject;import javax.security.auth.callback.Callback;import javax.security.auth.callback.CallbackHandler;import javax.security.auth.callback.NameCallback;import javax.security.auth.callback.PasswordCallback;import javax.security.auth.callback.UnsupportedCallbackException;import javax.security.auth.login.LoginException;import javax.security.auth.spi.LoginModule;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;public class LoginModuleImpl implements LoginModule {private Subject subject;private CallbackHandler callbackHandler;private String username;private String password;private Map sharedState;private Map options;private String url;private String driver;private String db_username;private String db_password;public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,Map<String, ?> options) {this.subject = subject;this.callbackHandler = callbackHandler;this.sharedState = sharedState;this.options = options;url = (String) options.get("url");driver = (String) options.get("driver");db_username = (String) options.get("db_username");db_password = (String) options.get("db_password");/*** 页面上的username 和password 由NameCallBack 和PasswordCallBack两个去获取* 有callbackHandler去回调,然后再把他们获取出来*/try {//TextInputCallback textInputCallback = new TextInputCallback("prompt");NameCallback nameCallback = new NameCallback("prompt");PasswordCallback passwordCallback = new PasswordCallback("prompt", false);callbackHandler.handle(new Callback[] { nameCallback, passwordCallback });username = nameCallback.getName();password = new String(passwordCallback.getPassword());} catch (IOException e) {e.printStackTrace();} catch (UnsupportedCallbackException e) {e.printStackTrace();}}public boolean login() throws LoginException {// 1.Query and compare// 2.用户名和密码对比正确 返回true,错误返回falseSystem.out.println("driver " + driver);System.out.println("url " + url);System.out.println("db_username " + db_username);System.out.println("db_password " + db_password);System.out.println("user " + username);System.out.println("password " + password);String dpwd = "";// String dtype = "";boolean flag = false;// 校验用户/*String sql = "select tp.name, tps.secretcode, tc.type from tperson tp "+ "inner join tcorp tc on tp.corpid = tc.objid "+ "inner join tpersonpsw tps on tp.objid = tps.objid where tp.name = ?";*/String sql = "select * from sec_user where username = ?";// 1.注册驱动// 2.获得连接Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {Class.forName(driver);conn = DriverManager.getConnection(url, db_username, db_password);// 3.创建statementps = conn.prepareStatement(sql);ps.setString(1, username);// 4.执行sql语句返回结果rs = ps.executeQuery();while (rs != null && rs.next()) {dpwd = rs.getString("password");flag = true;}} catch (SQLException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {try {if (conn != null) {conn.close();}if (ps != null) {ps.close();}if (rs != null) {rs.close();}} catch (SQLException e) {e.printStackTrace();}}if(flag == false){throw new LoginException("User is not exist !");}if (dpwd.equals(password)) {UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,password);subject.getPrincipals().add(authenticationToken);return true;} else {throw new LoginException("Username is not match the password ! ");}}public boolean commit() throws LoginException {return true;}public boolean abort() throws LoginException {return true;}public boolean logout() throws LoginException {return true;}}
jass中要的配置文件:WEB-INF/login.conf
JAASTest {sy.service.LoginModuleImpl requireddriver="com.mysql.jdbc.Driver"url="jdbc:mysql://localhost:3306/sy"db_username="root"db_password="1234"debug="true";};
这个文件有spring.xml文件中jaas文件读取。需要注意的是LoginModule这个接口的实现,是不能纳入到spring容器中去的,它是由jaas的标准API加载,所以这里的需要加入数据库的连接数据,供loginModul的实现类从数据去数据。
以下是jsp文件
logingpage.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%><%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%><%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><h1>Login</h1><div id="login-error">${error}</div><form action="../j_spring_security_check" method="post"><p><label for="j_username">Username</label> <input id="j_username"name="j_username" type="text" /></p><p><label for="j_password">Password</label> <input id="j_password"name="j_password" type="password" /></p><input type="submit" value="Login" /></form></body></html>
deniedpage.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><h1>你的权限不够!</h1><p>只有拥有Admin权限才能访问!</p><a href="/mybatis_security_session/auth/login">退出登录</a></body></html>
commonpage.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><h1>Common Page</h1><p>每个人都能访问的页面.</p><a href="/mybatis_security_session/main/admin"> Go AdminPage </a><br /><a href="/mybatis_security_session/auth/login">退出登录</a></body></html>
adminpage.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><h1>Admin Page</h1><p>管理员页面</p><a href="/mybatis_security_session/auth/login">退出登录</a></body></html>
项目我也上传了 ,若是需要可以搜索spring security+mybatis+springMVC 关键字 寻找资源
文章来自:http://blog.csdn.net/u013205003/article/details/51056510