springmvc maven搭建二之springmvc的security
上一篇文档初步搭建了一个springmvc的web工程,现在要来实现第二步咯。将登录校验整合到项目中,我用的是spring 3.0.2的版本,所以这里的登录用了security来处理。不多说,上代码。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <!-- spring核心监听器 配置ContextLoaderListener表示,该工程要以spring的方式启动。启动时会默认在/WEB-INF目录下查找 applicationContext.xml作为spring容器的配置文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 配置DispatcherServlet表示,该工程将采用springmvc的方式。启动时也会默认在/WEB-INF目录下查找XXX-servlet.xml作为配置文件,XXX就是DispatcherServlet的名字 -->
<!-- spring-servlet.xml -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <!-- spring security -->
<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> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-security.xml</param-value>
</context-param> <!-- 欢迎页 -->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
web.xml
login.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>title</title>
<script type="text/javascript"> function login() {
var loginName = "qiuj";
var loginPas = "qiuj";
if (loginName == "") {
$.messager.alert('提示','请输入用户名!','warning');
loginForm.username.focus();
return;
} else if(loginPas == "") {
$.messager.alert('提示','请输入密码!','warning');
loginForm.password.focus();
return;
} else {
loginForm.action = "j_spring_security_check";
loginForm.submit();
}
} </script>
</head>
<body>
<div>
<form id="loginForm" action="" method="post">
<input type="text" name="username" id="username"/>
<input type="password" name="password" id="password"/>
<input type="button" value="登录" onclick="login();"/>
</form>
</div>
</body>
</html>
login.jsp
有的这次相比上次没改动过的文件就不写啦,参照上文咯,因为这次添加了security,所以pom文件也要加依赖
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>com.qiuj</groupId>
<artifactId>springmvc-demo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>springmvc-demo 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-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.0.5.RELEASE</version>
</dependency> <dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_2.5_spec</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>springmvc-demo</finalName>
</build>
</project>
pom.xml
因为我这里security只负责登录处理,所以本着低耦合的设计思想,把这部分配置单拿出来了(这是有问题的,先上这个代码,下边会给正确的,别急)
applicationContext-security.xml
<?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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<!-- http安全配置 -->
<http use-expressions='true'
entry-point-ref="authenticationProcessingFilterEntryPoint"
access-denied-page="/access-denied.jsp">
<!-- 登录页面不过滤 -->
<intercept-url pattern="/login.jsp" filters="none" />
<!-- 修改注销页面 -->
<logout invalidate-session="true" logout-success-url="/login.jsp" logout-url="/j_spring_security_logout" />
</http> <!-- 登录验证器 -->
<beans:bean id="loginFilter"
class="com.test.service.security.MyUsernamePasswordAuthenticationFilter">
<!-- 处理登录 -->
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property>
<beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler"></beans:property>
<beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"></beans:property>
<beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>
</beans:bean>
<!-- 未登录的切入点 -->
<beans:bean id="loginLogAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/index.jsp"></beans:property>
</beans:bean>
<beans:bean id="simpleUrlAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.jsp"></beans:property>
</beans:bean> <!-- 用户拥有的权限:登录后取得用户所保有的权限信息 -->
<beans:bean id="myUserDetailService" class="com.test.service.security.AdminUserDetailServiceImpl">
</beans:bean> <!-- 未登录的切入点 -->
<beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp"></beans:property>
</beans:bean> <!-- 认证配置,使用userDetailsService提供的用户信息,实现了UserDetailsService的Bean -->
<authentication-manager alias="myAuthenticationManager">
<authentication-provider
user-service-ref="myUserDetailService">
<!-- 默认提供的PasswordEncoder包含plaintext, sha, sha-256, md5, md4, {sha},
{ssha}。 其中{sha}和{ssha}是专门为ldap准备的,plaintext意味着不对密码进行加密, 如果我们不设置PasswordEncoder,默认就会使用它。 -->
<password-encoder hash="plaintext" />
</authentication-provider>
</authentication-manager> </beans:beans>
applicationContext-security.xml
上两个java文件
AdminUserDetailServiceImpl.java
/**
*
*/
/**
* @author Administrator
*
*/
package com.test.service.security; import java.util.Set; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; public class AdminUserDetailServiceImpl implements UserDetailsService { //登录验证
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { Set<GrantedAuthority> grantedAuths = null; //封装成spring security的user
User userdetail = new User("", "",
true, // 账号状态 0 表示停用 1表示启用
true, true, true, grantedAuths // 用户的权限
);
return userdetail;
} }
AdminUserDetailServiceImpl.java
MyUsernamePasswordAuthenticationFilter.java
/**
*
*/
/**
* @author Administrator
*
*/
package com.test.service.security; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.security.authentication.AuthenticationServiceException;
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; public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ public static final String USERNAME = "username";
public static final String PASSWORD = "password"; @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
} String username = obtainUsername(request);
String password = obtainPassword(request); if (username == null) {
username = "";
} if (password == null) {
password = "";
} username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest);
} @Override
protected String obtainUsername(HttpServletRequest request) {
Object obj = request.getParameter(USERNAME);
return null == obj ? "" : obj.toString();
} @Override
protected String obtainPassword(HttpServletRequest request) {
Object obj = request.getParameter(PASSWORD);
return null == obj ? "" : obj.toString();
}
}
MyUsernamePasswordAuthenticationFilter.java
项目结构(注意:我这里给的都是按照我的结构配置的,如不一样,要自己客户化啊)
好了,这就是第一次运行了
登录。。。。。。报错。。。。404。。。似曾相识的错误啊
应该applicationContext-security.xml文件配置哪里有问题。。。
瞎调了半天,觉得还是要认真理解配置都代表啥才能更好的对症下药。。。
配置自定义custom-filter---------问题在这里
这是第一次配置的截图,这里的bean并没有对应的自定义过滤器调用啊啊啊啊啊。。。。
修改为:
好 上代码
applicationContext-security.xml
<?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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<!-- http安全配置 -->
<http use-expressions="true"
entry-point-ref="authenticationProcessingFilterEntryPoint">
<!-- 登录页面不过滤 -->
<intercept-url pattern="/login.jsp" filters="none" />
<!-- 只有权限才能访问的请求 -->
<intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
<custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />
<!-- 修改注销页面 -->
<logout invalidate-session="true" logout-success-url="/login.jsp" logout-url="/j_spring_security_logout" />
</http> <!-- 登录验证器 -->
<beans:bean id="loginFilter"
class="com.test.service.security.MyUsernamePasswordAuthenticationFilter">
<!-- 处理登录 -->
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property>
<beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler"></beans:property>
<beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"></beans:property>
<beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>
</beans:bean>
<!-- 未登录的切入点 -->
<beans:bean id="loginLogAuthenticationSuccessHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/login"></beans:property>
</beans:bean>
<beans:bean id="simpleUrlAuthenticationFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/login.jsp"></beans:property>
</beans:bean> <!-- 用户拥有的权限:登录后取得用户所保有的权限信息 -->
<beans:bean id="myUserDetailService" class="com.test.service.security.AdminUserDetailServiceImpl">
</beans:bean> <!-- 未登录的切入点 -->
<beans:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp"></beans:property>
</beans:bean> <!-- 认证配置,使用userDetailsService提供的用户信息,实现了UserDetailsService的Bean -->
<authentication-manager alias="myAuthenticationManager">
<authentication-provider
user-service-ref="myUserDetailService">
<!-- 默认提供的PasswordEncoder包含plaintext, sha, sha-256, md5, md4, {sha},
{ssha}。 其中{sha}和{ssha}是专门为ldap准备的,plaintext意味着不对密码进行加密, 如果我们不设置PasswordEncoder,默认就会使用它。 -->
<password-encoder hash="plaintext" />
</authentication-provider>
</authentication-manager> </beans:beans>
applicationContext-security.xml
顺便为了规范化,也将欢迎页和登录跳转的成功页修改了
MyUsernamePasswordAuthenticationFilter.java
/**
*
*/
/**
* @author Administrator
*
*/
package com.test.service.security; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.security.authentication.AuthenticationServiceException;
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; public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ public static final String USERNAME = "username";
public static final String PASSWORD = "password"; @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
} String username = obtainUsername(request);
String password = obtainPassword(request); if (username == null) {
username = "";
} if (password == null) {
password = "";
} username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest);
} @Override
protected String obtainUsername(HttpServletRequest request) {
Object obj = request.getParameter(USERNAME);
return null == obj ? "" : obj.toString();
} @Override
protected String obtainPassword(HttpServletRequest request) {
Object obj = request.getParameter(PASSWORD);
return null == obj ? "" : obj.toString();
}
}
MyUsernamePasswordAuthenticationFilter.java
AdminUserDetailServiceImpl.java
/**
*
*/
/**
* @author Administrator
*
*/
package com.test.service.security; import java.util.ArrayList;
import java.util.Collection; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; public class AdminUserDetailServiceImpl implements UserDetailsService { //登录验证
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
auths.add(new GrantedAuthorityImpl("ROLE_USER"));
String password = "1234";
//String password = loginUser.getLoginPW();
//封装成spring security的user
User userdetail = new User(username, password,
true, // 账号状态 0 表示停用 1表示启用
true, true, true, auths // 用户的权限
);
return userdetail;
} }
AdminUserDetailServiceImpl.java
跑起来
目前这个版本还没有用到数据库判断权限啊 用户啊之类的,都是写死的配置,先初步出来一版吧,感觉对整体有个概念,然后想要理解。。。spring源码,I'm coming。。。
源码还是依旧百度云盘吧。。。干巴呆
最新文章
- SharePoint 2013技巧分享系列 - Active Directory同步显示用户照片
- mysql in 命令
- WPF笔记一
- ASP.NET Core Web开发学习笔记-1介绍篇
- Delphi获取系统服务描述信息
- Smarty属性
- (10)Python函数
- jsp fmt标签格式化double数字
- office 2010 正在配置Microsoft Office ...
- XSS攻击防御篇
- Flex父子窗体相互调用
- setTimeout解读
- c# 之Web.config
- 2. C++11 构造函数相关
- 160419、CSS3实现32种基本图形
- Kafka性能之道
- CSS3鼠标悬停边框线条动画按钮
- Shader之性能优化
- vue - audio标签
- Python Base Two