在SpringMVC+Spring工程中使用SpringSecurity4.2.3
原创Spring Security 为基于Java EE 企业软件应用提供全面的安全服务(官方)。使用 Spring Securituy 可以方便地为一个 Web 进行用户登录认证、权限控制。可以通过轮廓法和Java配置方式。以下是两种方法:
准备
1 Maven 坐标
org.springframework.security
spring-security-web
4.2.3.RELEASE
org.springframework.security
spring-security-config
4.2.3.RELEASE
org.springframework.security
spring-security-taglibs
4.2.3.RELEASE
2 在 web.xml 中配置 Spring Security 过滤器
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
方式一 轮廓法
1 添加配置文件 spring-security.xml,并在 web.xml 在以下位置扫描此配置文件
2 配置文件中使用的自定义类。
2.1 UserDetailsServiceImpl
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import diary.mapper.UserMapper;
import diary.pojo.User;
/**
* 根据用户提交的用户名查询用户信息。
*/
public class UserDetailsServiceImpl implements UserDetailsService {
@Resource
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if(StringUtils.isEmpty(username)) {
throw new BadCredentialsException("用户名不能为空");
}
UserDetails userDetails = null;
// 根据用户名从数据库中查询用户信息,按照自己的业务规则编写。
User user = this.userMapper.getUserByUsername(username);
if(user == null) {
throw new BadCredentialsException("用户名不存在");
}
userDetails = new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(), // 存储在数据库中的密码
true, // 用户是否处于激活状态
true, // 帐户是否已过期
true, // 证书是否已过期
true, // 账号是否被锁定
AuthorityUtils.createAuthorityList("ROLE_" + user.getType())); // 用户角色列表,必须为 ROLE_ 开头
return userDetails;
}
}
2.2 MyMessageDigestPasswordEncoder
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder;
import diary.common.util.MD5Util;
/**
* 用于自定义用户提交的密码。
*/
public class MyMessageDigestPasswordEncoder extends MessageDigestPasswordEncoder {
public MyMessageDigestPasswordEncoder(String algorithm) {
super(algorithm);
}
/**
* encPass:用户的密码真的是
* raw:用户提交的密码
*
*/
@Override
public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
if(StringUtils.isEmpty(rawPass)) {
throw new BadCredentialsException("密码不能为空");
}
return encPass.equals(MD5Util.md5(rawPass));
}
}
2.3 AuthenticationSuccessHandlerImpl
import java.io.IOException;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import diary.mapper.UserMapper;
import diary.pojo.User;
/**
* 对于成功登录身份验证后执行的操作
*/
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
@Resource
private UserMapper userMapper;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
// UserDetails 用户名等信息存储在
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
// 获取用户信息,并根据您自己的业务规则进行编写。
User user = this.userMapper.getUserByUsername(username);
// 将用户放入 Session
request.getSession().setAttribute("currUser", user);
// 跳转到主页
response.sendRedirect(request.getContextPath() + "/home.html");
}
}
2.4 AuthenticationFailureHandlerImpl
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
/**
* 用于在用户登录身份验证失败后执行的操作
*/
public class AuthenticationFailureHandlerImpl implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
// AuthenticationException 存储异常信息,将其取出并放入 Request 转发到登录页。
request.setAttribute("error", exception.getMessage());
request.getRequestDispatcher("/login").forward(request, response);
}
}
方式二 注解+Java 一种代码配置方法
这个类等同于上面的 spring-security.xml,其中各种配置可以对应于 spring-security.xml 中的配置项。四个定制类保持不变。需要强调的是,时间必须到位。 Spring 在扫描配置文件中的此类。所在的包。
package diary.security.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import diary.security.AuthenticationFailureHandlerImpl;
import diary.security.AuthenticationSuccessHandlerImpl;
import diary.security.MyMessageDigestPasswordEncoder;
import diary.security.UserDetailsServiceImpl;
/**
* 批注方法配置 Spring Security,请注意需要在 Spring 扫描配置文件中的此类。
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
// 设置无阻止规则
web.ignoring().antMatchers("/login", "/error/**", "/css/**", "/help/**", "/img/**", "/js/**", "/res/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 自定义 accessDecisionManager 门禁控制器,并打开表情语言
http.authorizeRequests()
.expressionHandler(webSecurityExpressionHandler()) // 启用 SpEL 表达式
.antMatchers("/user/**").hasRole("0") // 访问 /user/** 必须有角色 "0",当使用标签时
.and().exceptionHandling().accessDeniedPage("/error/403") // 在指定的登录身份验证成功后,用户访问未经授权的 URL 将跳转的 URL
.and().authorizeRequests().anyRequest().authenticated(); // 指定需要登录所有请求
// 打开默认登录页面
// http.formLogin();
// 自定义登录页面
http.formLogin().loginPage("/login") // 指定登录页面
.loginProcessingUrl("/user/doLogin") // 执行登录操作 URL
.usernameParameter("username") // 用户请求登录时提交的用户名参数
.passwordParameter("password") // 用户请求登录时提交的密码参数
.failureHandler(this.authenticationFailureHandler()) // 定义登录身份验证失败后应执行的操作
.successHandler(this.authenticationSuccessHandler()); // 定义登录身份验证后执行的操作
// 自定义注销
http.logout().logoutUrl("/user/logout") // 执行注销操作。 URL
.logoutSuccessUrl("/login") // 注销成功后跳转的页面
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
// session 管理
http.sessionManagement().sessionFixation().none().maximumSessions(1);
// 禁用 CSRF
http.csrf().disable();
}
/**
* 登录身份验证配置
*/
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(this.userDetailsService())
.passwordEncoder(this.messageDigestPasswordEncoder());
}
/**
* 使用需要继承的自定义登录密码加密规则。 MessageDigestPasswordEncoder
*/
@Bean(name = "myMessageDigestPasswordEncoder")
public MessageDigestPasswordEncoder messageDigestPasswordEncoder() {
return new MyMessageDigestPasswordEncoder("md5");
}
/**
* 使用自定义登录身份验证失败处理类,需要继承 AuthenticationFailureHandler
*/
@Bean(name = "authenticationFailureHandlerImpl")
public AuthenticationFailureHandler authenticationFailureHandler() {
return new AuthenticationFailureHandlerImpl();
}
/**
* 使用自定义登录身份验证成功处理类需要继承 AuthenticationSuccessHandler
*/
@Bean(name = "authenticationSuccessHandlerImpl")
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return new AuthenticationSuccessHandlerImpl();
}
@Bean(name = "userDetailsServiceImpl")
public UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl();
}
// 表达式控制器
@Bean(name = "expressionHandler")
public DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {
return new DefaultWebSecurityExpressionHandler();
}
}
另附
您可以在前端页面上使用它。 Spring Security 提供的标签控制元素的显示。
可参考 http://blog.csdn.net/running_snail_/article/details/7167771
下面是一个简单的例子:
<%-- 只有一个角色“0“用户可以看到它标签 --%>
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除
itfan123





