spring security4.2基于User Schema登陆
工程结构
引入maven依赖
<ssecurity.version>4.2.3.RELEASE</ssecurity.version>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${ssecurity.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${ssecurity.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${ssecurity.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${ssecurity.version}</version>
</dependency>
User Schema
# t_user
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(100) NOT NULL,
`password` varchar(20) NOT NULL,
`enabled` int(1) NOT NULL,
PRIMARY KEY (`id`)
)
INSERT INTO `security`.`t_user` (`id`, `username`, `password`, `enabled`)
VALUES ('1', 'simon', '111', '1'), ('2', 'jhon', '111', '1');
# t_user_role
CREATE TABLE `t_user_role` (
`username` varchar(100) NOT NULL,
`rolename` varchar(100) NOT NULL
)
INSERT INTO `security`.`t_user_role` (`username`, `rolename`) VALUES ('simon', 'ROLE_USER');
INSERT INTO `security`.`t_user_role` (`username`, `rolename`) VALUES ('simon', 'ROLE_ADMIN');
INSERT INTO `security`.`t_user_role` (`username`, `rolename`) VALUES ('jhon', 'ROLE_USER');
// 也可以和`spring security`官网的一样
create table users(
username varchar_ignorecase(50) not null primary key,
password varchar_ignorecase(50) not null,
enabled boolean not null
);
create table authorities (
username varchar_ignorecase(50) not null,
authority varchar_ignorecase(50) not null,
constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);
配置文件
spring-context.xml
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.shes.xkjy">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
</context:component-scan>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/security"/>
<property name="user" value="root"/>
<property name="password" value="111111"/>
</bean>
</beans>
spring-mvc.xml
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.shes.xkjy">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
</context:component-scan>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
spring-security.xml
<?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:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<security:http security="none" pattern="/custom/login"/>
<security:http auto-config="false">
<!--spring security4中一定需要csrf为true-->
<security:csrf disabled="true"/>
<security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<security:form-login login-page="/custom/login"
password-parameter="pass_param"
username-parameter="user_param"
default-target-url="/success"
authentication-failure-url="/custom/login?error_auth=true"/>
<security:access-denied-handler ref="customAccessDenyHandler"/>
<security:logout />
</security:http>
<bean id="customAccessDenyHandler" class="com.shes.xkjy.handler.CustomAccessDenyHandler" />
<security:authentication-manager>
<security:authentication-provider>
<security:jdbc-user-service data-source-ref="dataSource"
users-by-username-query="SELECT
username,password,
CASE enabled WHEN 1 THEN 'true' ELSE 'false' END enabled FROM t_user tu WHERE tu.username=?;"
authorities-by-username-query="SELECT tu.username, tur.rolename
where tu.username=tur.username AND tu.username=?;"
/>
</security:authentication-provider>
</security:authentication-manager>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring-context.xml,
classpath:spring-security.xml
</param-value>
</context-param>
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value>classpath:logback.xml</param-value>
</context-param>
<listener>
<listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
//spring security requires
<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>
</web-app>
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 一是把日志信息转换成字节数组,二是把字节数组写入到输出流 -->
<encoder>
<Pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%5level] %logger{0} %msg%n</Pattern>
<!-- 这里根部不需要设置UTF-8编码,反而设置控制台就会乱码
<charset>UTF-8</charset>
-->
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
自定义登陆页面login.jsp
<%--
Created by IntelliJ IDEA.
User: dxjm
Date: 2017/12/18
Time: 21:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>login</title>
</head>
<body>
<h1>自定义登陆</h1>
<c:if test="${param.error_auth}">
<h3 style="color: red">认证失败!!</h3>
</c:if>
<form method="post" action="${pageContext.request.contextPath}/login">
username: <input type="text" name="user_param" /><br>
password: <input type="password" name="pass_param" /><br>
<input type="submit" name="submit" value="submit" />
</form>
</body>
</html>
CustomAccessDenyHandler.java
public class CustomAccessDenyHandler implements AccessDeniedHandler {
public static final String DEF_ERROR_PAGE_PATH = "/deny";
@Override
public void handle(HttpServletRequest request,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.sendRedirect(request.getContextPath()+DEF_ERROR_PAGE_PATH);
}
}