spring security 配置使用
这篇文章仅限开发者已经会搭建spring+springMVC+hibernate框架的基础上
一、添加jar包
一般springSecurity的jar包下载最好是与自己spring版本一致
因为我用的spring相关jar包版本是4.2.4,所以我下载的springSecurity版本也是4.2.4-release
这里传授一下如何快速下载对应的springSecurity版本
http://repo.spring.io/libs-release-local/org/springframework/security/spring-security/3.2.3.RELEASE/spring-security-3.2.3.RELEASE-dist.zip
将3.2.3.release换成自己想要的版本就可以下载自己想要的版本
具体可以看这篇博客https://www.cnblogs.com/yjmyzz/p/3847364.html
下载完成将spring-security-config
spring-security-core
spring-security-web
spring-security-taglibs
四个jar包copy到项目的lib文件夹下面
二、配置springSecurity文件
这里直接贴上代码,在代码中一行一行讲述相关配置
<?xml version="1.0" encoding="UTF-8"?>
<!-- 这一块可以理解为需要引用的外部文件 -->
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<http use-expressions="false">
<!-- 通过这种配置来控制哪些界面不需要控制权限 -->
<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<!--这种写法是拦截所有其他界面,除非具备access后面的权限-->
<intercept-url pattern="/**" access="ROLE_ADMIN" />
<!-- 配置登录页面地址login-page、登录失败后的跳转地址authentication-failure-url -->
<form-login login-page='/login.jsp'
authentication-failure-url='/login.jsp?error=true'
default-target-url="/index.jsp" />
<!-- 登出功能 -->
<logout logout-success-url="/loggedout.jsp" />
<!-- 这个好像是开启什么防御,什么鬼-->
<csrf disabled="true" />
<!-- 登录要实现的一些过滤以及事件处理 具体配置在下面 -->
<custom-filter ref="authenticationProcessingFilter" before="FORM_LOGIN_FILTER" />
<!-- 设置session失效之后跳转的界面 -->
<session-management invalid-session-url="/timeout.jsp">
<!-- 设置最大访问量 -->
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</session-management>
</http>
<!-- 要走的过滤器 LoginFilter是自定义的类-->
<beans:bean id="authenticationProcessingFilter" class="cn.yjz.java.controller.LoginFilter">
<!-- 下面这三行在后面都有详细配置 -->
<beans:property name="authenticationSuccessHandler" ref="loginSuccessHandler"></beans:property>
<beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler"></beans:property>
<beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
</beans:bean>
<!-- 定制登录过滤器 LoginSuccessHandler是自定义的类 -->
<beans:bean id="loginSuccessHandler" class="cn.yjz.java.controller.LoginSuccessHandler">
<beans:property name="defaultTargetUrl">
<!-- 登录成功后转发到该页面 -->
<beans:value>/success.jsp</beans:value>
</beans:property>
</beans:bean>
<!-- 失败要走的处理,我相信这里也可以自己自定义一个 -->
<beans:bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl">
<!-- 登录失败后转发到该页面 -->
<beans:value>/login.jsp?error=true</beans:value>
</beans:property>
</beans:bean>
<!-- 使用自定义类myUserDetailsService从数据库获取用户信息 -->
<!-- 情况二:从数据库读取 user-service-ref="myUserDetailsService " -->
<authentication-manager alias="authenticationManager">
<authentication-provider <!-- user-service-ref="myUserDetailsService -->">
<!-- 加密 -->
<!-- <password-encoder hash="md5">
</password-encoder> -->
<!-- <user-service>
账户情况一:写死
<user name="admin" password="admin" authorities="ROLE_ADMIN" />
</user-service> -->
</authentication-provider>
</authentication-manager>
<!-- 配置从数据库读取的操作 这一种开发者自己去研究吧,首先要建表,在表中插入几条测试数据 然后从表中查出来-->
<beans:bean id = "myUserDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<beans:property name="dataSource" ref="dataSource"></beans:property>
<beans:property name="usersByUsernameQuery" value="select name, pwd, true from t_admin where name = ?"></beans:property>
<beans:property name="authoritiesByUsernameQuery" value="select u.name, r.role, true from t_admin u,
t_group_user gu,
t_group g,
t_group_role gr,
t_role r
where u.id = gu.userid
and gu.groupid = g.id
and g.id = gr.groupid
and gr.roleid = r.id
and u.name = ?;"></beans:property>
</beans:bean>
<!-- 暂且理解为找到jdbc的配置文件 -->
<beans:bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<beans:property name="location">
<!-- 明明我将文件放在src.main下面的config包文件下面,为什么寻找的路径却在这里 是因为项目编译之后会在web-inf下面生成 -->
<beans:value>/WEB-INF/classes/cn/yjz/config/jdbc.properties</beans:value>
</beans:property>
</beans:bean>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="${jdbc.driver}" />
<beans:property name="url" value="${jdbc.url}" />
<beans:property name="username" value="${jdbc.username}" />
<beans:property name="password" value="${jdbc.password}" />
</beans:bean>
<!-- 自定义消息 -->
<!-- <b:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<b:property name="basename"
value="classpath:org/springframework/security/messages" />
</b:bean> -->
</beans:beans>
以上两个自定义类,我也简单贴出来
1、
public class LoginFilter extends UsernamePasswordAuthenticationFilter implements Serializable{
private static final long serialVersionUID = 488268309523329488L;
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
System.out.println("此处是做登录过滤");
return super.attemptAuthentication(request, response);
}
}
2、
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler implements Serializable{
private static final long serialVersionUID = 2215732280244695604L;
public LoginSuccessHandler() {
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
System.out.println("成功登录之后的处理");
System.out.println(userDetails.getPassword() + "\n" + userDetails.getUsername() + "\n");
super.onAuthenticationSuccess(request, response, authentication);
}
}
三、web文件配置
在我的理解中,其实所有的其他配置最终都要走到web.xml
这里有关其他的配置我就不贴出来了以免混乱
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 这里如果有多个配置文件,用,隔开-->
<param-value>/WEB-INF/classes/cn/yjz/config/springMVC-servlet.xml,
/WEB-INF/classes/cn/yjz/config/springSecurity.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- springsecurity过滤器 -->
<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>
四、登录界面.jsp的编写
其他的timeout.jsp ,logout.jsp, index.jsp我就不建了,以上配置中这些文件只要在webroot文件夹下就可以生效。
登录界面
在登录界面的顶部添加
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
启用c标签 另外不同的springSecurity版本不一样登录界面写法不同,所以在写之前上网看看对应版本的写法
<body οnlοad="document.loginForm.j_username.focus();">
<form name="loginForm" action="<c:url value='/login'/>" method="post">
<!-- 登录失败后,显示之前的登录名 -->
用户名:<input type='text' name='username' class="txtinput"
value='<c:if test="${not empty param.login_error}" >
<c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>' />
<br />
密码:<input type='password' name='password' class="txtinput" />
<br />
<input type="checkbox" name="_spring_security_remember_me" />
保存登录信息
<input name="submit" type="submit" value="提交" />
<input name="reset" type="reset" value="重置" />
</form>
<br />
<!-- 显示登录失败原因 -->
<c:if test="${not empty param.error}">
<font color="red"> 登录失败<br />
<br />
原因: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />. </font>
</c:if>
</body>
这篇文章仅限开发者已经会搭建spring+springMVC+hibernate框架的基础上
一、添加jar包
一般springSecurity的jar包下载最好是与自己spring版本一致
因为我用的spring相关jar包版本是4.2.4,所以我下载的springSecurity版本也是4.2.4-release
这里传授一下如何快速下载对应的springSecurity版本
http://repo.spring.io/libs-release-local/org/springframework/security/spring-security/3.2.3.RELEASE/spring-security-3.2.3.RELEASE-dist.zip
将3.2.3.release换成自己想要的版本就可以下载自己想要的版本
具体可以看这篇博客https://www.cnblogs.com/yjmyzz/p/3847364.html
下载完成将spring-security-config
spring-security-core
spring-security-web
spring-security-taglibs
四个jar包copy到项目的lib文件夹下面
二、配置springSecurity文件
这里直接贴上代码,在代码中一行一行讲述相关配置
<?xml version="1.0" encoding="UTF-8"?>
<!-- 这一块可以理解为需要引用的外部文件 -->
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<http use-expressions="false">
<!-- 通过这种配置来控制哪些界面不需要控制权限 -->
<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/index.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<!--这种写法是拦截所有其他界面,除非具备access后面的权限-->
<intercept-url pattern="/**" access="ROLE_ADMIN" />
<!-- 配置登录页面地址login-page、登录失败后的跳转地址authentication-failure-url -->
<form-login login-page='/login.jsp'
authentication-failure-url='/login.jsp?error=true'
default-target-url="/index.jsp" />
<!-- 登出功能 -->
<logout logout-success-url="/loggedout.jsp" />
<!-- 这个好像是开启什么防御,什么鬼-->
<csrf disabled="true" />
<!-- 登录要实现的一些过滤以及事件处理 具体配置在下面 -->
<custom-filter ref="authenticationProcessingFilter" before="FORM_LOGIN_FILTER" />
<!-- 设置session失效之后跳转的界面 -->
<session-management invalid-session-url="/timeout.jsp">
<!-- 设置最大访问量 -->
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</session-management>
</http>
<!-- 要走的过滤器 LoginFilter是自定义的类-->
<beans:bean id="authenticationProcessingFilter" class="cn.yjz.java.controller.LoginFilter">
<!-- 下面这三行在后面都有详细配置 -->
<beans:property name="authenticationSuccessHandler" ref="loginSuccessHandler"></beans:property>
<beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler"></beans:property>
<beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
</beans:bean>
<!-- 定制登录过滤器 LoginSuccessHandler是自定义的类 -->
<beans:bean id="loginSuccessHandler" class="cn.yjz.java.controller.LoginSuccessHandler">
<beans:property name="defaultTargetUrl">
<!-- 登录成功后转发到该页面 -->
<beans:value>/success.jsp</beans:value>
</beans:property>
</beans:bean>
<!-- 失败要走的处理,我相信这里也可以自己自定义一个 -->
<beans:bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl">
<!-- 登录失败后转发到该页面 -->
<beans:value>/login.jsp?error=true</beans:value>
</beans:property>
</beans:bean>
<!-- 使用自定义类myUserDetailsService从数据库获取用户信息 -->
<!-- 情况二:从数据库读取 user-service-ref="myUserDetailsService " -->
<authentication-manager alias="authenticationManager">
<authentication-provider <!-- user-service-ref="myUserDetailsService -->">
<!-- 加密 -->
<!-- <password-encoder hash="md5">
</password-encoder> -->
<!-- <user-service>
账户情况一:写死
<user name="admin" password="admin" authorities="ROLE_ADMIN" />
</user-service> -->
</authentication-provider>
</authentication-manager>
<!-- 配置从数据库读取的操作 这一种开发者自己去研究吧,首先要建表,在表中插入几条测试数据 然后从表中查出来-->
<beans:bean id = "myUserDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<beans:property name="dataSource" ref="dataSource"></beans:property>
<beans:property name="usersByUsernameQuery" value="select name, pwd, true from t_admin where name = ?"></beans:property>
<beans:property name="authoritiesByUsernameQuery" value="select u.name, r.role, true from t_admin u,
t_group_user gu,
t_group g,
t_group_role gr,
t_role r
where u.id = gu.userid
and gu.groupid = g.id
and g.id = gr.groupid
and gr.roleid = r.id
and u.name = ?;"></beans:property>
</beans:bean>
<!-- 暂且理解为找到jdbc的配置文件 -->
<beans:bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<beans:property name="location">
<!-- 明明我将文件放在src.main下面的config包文件下面,为什么寻找的路径却在这里 是因为项目编译之后会在web-inf下面生成 -->
<beans:value>/WEB-INF/classes/cn/yjz/config/jdbc.properties</beans:value>
</beans:property>
</beans:bean>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="${jdbc.driver}" />
<beans:property name="url" value="${jdbc.url}" />
<beans:property name="username" value="${jdbc.username}" />
<beans:property name="password" value="${jdbc.password}" />
</beans:bean>
<!-- 自定义消息 -->
<!-- <b:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<b:property name="basename"
value="classpath:org/springframework/security/messages" />
</b:bean> -->
</beans:beans>
以上两个自定义类,我也简单贴出来
1、
public class LoginFilter extends UsernamePasswordAuthenticationFilter implements Serializable{
private static final long serialVersionUID = 488268309523329488L;
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
System.out.println("此处是做登录过滤");
return super.attemptAuthentication(request, response);
}
}
2、
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler implements Serializable{
private static final long serialVersionUID = 2215732280244695604L;
public LoginSuccessHandler() {
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
System.out.println("成功登录之后的处理");
System.out.println(userDetails.getPassword() + "\n" + userDetails.getUsername() + "\n");
super.onAuthenticationSuccess(request, response, authentication);
}
}
三、web文件配置
在我的理解中,其实所有的其他配置最终都要走到web.xml
这里有关其他的配置我就不贴出来了以免混乱
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 这里如果有多个配置文件,用,隔开-->
<param-value>/WEB-INF/classes/cn/yjz/config/springMVC-servlet.xml,
/WEB-INF/classes/cn/yjz/config/springSecurity.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- springsecurity过滤器 -->
<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>
四、登录界面.jsp的编写
其他的timeout.jsp ,logout.jsp, index.jsp我就不建了,以上配置中这些文件只要在webroot文件夹下就可以生效。
登录界面
在登录界面的顶部添加
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
启用c标签 另外不同的springSecurity版本不一样登录界面写法不同,所以在写之前上网看看对应版本的写法
<body οnlοad="document.loginForm.j_username.focus();">
<form name="loginForm" action="<c:url value='/login'/>" method="post">
<!-- 登录失败后,显示之前的登录名 -->
用户名:<input type='text' name='username' class="txtinput"
value='<c:if test="${not empty param.login_error}" >
<c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>' />
<br />
密码:<input type='password' name='password' class="txtinput" />
<br />
<input type="checkbox" name="_spring_security_remember_me" />
保存登录信息
<input name="submit" type="submit" value="提交" />
<input name="reset" type="reset" value="重置" />
</form>
<br />
<!-- 显示登录失败原因 -->
<c:if test="${not empty param.error}">
<font color="red"> 登录失败<br />
<br />
原因: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />. </font>
</c:if>
</body>
这样的话就全部配置完成了,然而这只是简单的配置,我接下来是要使用springSecurity实现注册登录,权限控制。
下面是实现效果截图 失败
成功