ch04:限制IP,增加密码修改功能
2017-07-20 本文已影响0人
伊娃瓦力
限制IP
如果有IP访问限制的要求,可以使用SpringEl表达式描述具体IP或者IP子网:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/assets/**").permitAll()
.antMatchers("/**").access("hasIpAddress('192.168.109.136') and hasRole('USER')")
.and().formLogin().loginPage("/login.jsp").permitAll().loginProcessingUrl("/login")
.and().rememberMe()
.and().csrf().disable();
}
这样就限制了用户必须是IP地址为192.168.109.136的用户才能访问,此外如果将IP写为192.168.109.0代表192.168.109.1~192.168.109.255网段可以访问
修改密码
用户有变更密码的需求,变更密码一般需要提供用户原密码等额外信息,此外还需要重复输入密码,以保证用户输入正确等内容,这些已经超出Spring Security的范围,其实大家关心的是如何获得当前已认证的用户信息,并且能够修改它的密码
根据ch02的讲解,Spring Security认证后,当前认证用户被存储到SecurityContextHolder中,这个类提供了静态方法SecurityContextHolder.getContext().getAuthentication()就可以获得当前用户对象,如果需要修改其密码,只需要自定义服务,完成修改功能即可。
- 修改WebSecurityConfigurerAdapter,增加用户信息获取服务UserDetailService,该接口是Spring Security用户获取用户信息的接口,扩展该接口可以通过数据库、LDAP等服务获取用户信息,用户信息以UserDetails表示,通过扩展该接口可以提供额外的用户信息。
/**
* 定义用户信息获取服务
* 这里使用内存方式获取用户信息,并添加了一个用户
*
* @return
*/
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
return manager;
}
- 用户修改密码服务
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Description:
* 1.获取已认证用户
* 2.获取用户管理服务
* 3.修改密码
* 4.刷新认证
*
* @param password
* @return
*
* @Author: 瓦力
* @Date: 2017/7/20 14:31
*/
@RequestMapping(value = "/changePassword", method = RequestMethod.POST)
public String changePassword(@RequestParam("password") String password) {
//获得当前用户
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (InMemoryUserDetailsManager.class.isInstance(userDetailsService)) {
InMemoryUserDetailsManager manager = (InMemoryUserDetailsManager) userDetailsService;
manager.changePassword(principal.getPassword(), password);//spring security已实现了密码修改功能
}
SecurityContextHolder.clearContext();//终止当前认证用户
return "redirect:/index.jsp";
}
}public class UserServiceController {
//获取用户信息服务
@Autowired
UserDetailsService userDetailsService;
/**
* Description:跳转到用户密码修改界面
*
* @return
*
* @Author: 瓦力
* @Date: 2017/7/20 14:59
*/
@RequestMapping(value = "/changePassword", method = RequestMethod.GET)
public String changePassword() {
return "redirect:/changePassword.jsp";
}
- 用户修改密码界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Change Password</h2>
<div>
<h2>修改密码</h2>
<form action="/changePassword" method="post">
<input type="password" name="password" placeholder="Password">
<input type="submit" value="Change Password">
</form>
</div>
</body>
</html>
- index.jsp增加链接
<h2>修改密码</h2>
<a href="/changePassword.jsp">修改密码</a>
通过以上代码,就可以实现密码修改,读者可以试试,其实以上内容与Spring Security的关系并不大,这章主要是为读者介绍Spring Security是如何保存认证用户信息以及如何获得用户信息,这两建立基本概念,为随后的使用数据库方式获取用户信息奠定基础。
InMemoryUserDetailsManager 实现了UserDetailsManager,UserDetailsManager扩展了UserDetailsService,提供了许多内置的用户管理方法:
/**
* Create a new user with the supplied details.
*/
void createUser(UserDetails user);
/**
* Update the specified user.
*/
void updateUser(UserDetails user);
/**
* Remove the user with the given login name from the system.
*/
void deleteUser(String username);
/**
* Modify the current user's password. This should change the user's password in the
* persistent user repository (datbase, LDAP etc).
*
* @param oldPassword current password (for re-authentication if required)
* @param newPassword the password to change to
*/
void changePassword(String oldPassword, String newPassword);
/**
* Check if a user with the supplied login name exists in the system.
*/
boolean userExists(String username);
借助这些方法,我们可以继续完善用户管理功能
代码示例https://github.com/wexgundam/spring.security/tree/master/ch04