ch04:限制IP,增加密码修改功能

限制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()就可以获得当前用户对象,如果需要修改其密码,只需要自定义服务,完成修改功能即可。

  1. 修改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;
    }
  1. 用户修改密码服务
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";
    }
  1. 用户修改密码界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


Change Password

修改密码

  1. index.jsp增加链接
    

修改密码

修改密码

通过以上代码,就可以实现密码修改,读者可以试试,其实以上内容与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

你可能感兴趣的:(ch04:限制IP,增加密码修改功能)