java - Spring security 动态授权

标签 java spring spring-mvc spring-boot spring-security

我使用 spring security 和 spring boot 来开发应用程序,以保护我的 api 的特定端点,我使用 SecurityConf 如下:

 @Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception {
    auth
    .inMemoryAuthentication()
    .passwordEncoder(passwordEncoder)
    .withUser(username).password(password).roles(ADMIN_ROLE);
}

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
    .csrf().disable()
    .authorizeRequests()
    .antMatchers("/api/survey/report/**").hasRole(ADMIN_ROLE)
    .and().formLogin()
    .and().logout();
}

密码和用户名是在开始时从数据库加载的。

一切似乎都工作正常,但现在我必须实现一种方法来更改管理员密码,我实现了存储库、服务和 Controller 方法来使用新的加密密码更改数据库,但就目前情况而言,更改除非我重新启动应用程序(这会导致类加载新的用户名和密码),否则不会反射(reflect)在应用程序中。

如何使应用程序从数据库中重新加载新的用户名和密码,而无需重新启动它? (在生产中,这是一个将不间断运行的应用程序)

这是密码更改方法的 Controller :

@RequestMapping(value = "/change", method = RequestMethod.POST)
public ResponseEntity changePassword(@RequestBody Password password) {

    return passwordService.updatePassword(password);
}

这是服务方法:

public ResponseEntity updatePassword(Password password) {
    Administrator administrator = administratorRepository.findAdministrator();
    if (passwordEncoder.matches(password.getOldPassword(), administrator.getPassword())) {
        String encodePassword = passwordEncoder.encode(password.getNewPassword());
        administrator.setPassword(encodePassword);
        administratorRepository.updateAdministrator(administrator);

        return new ResponseEntity(HttpStatus.OK);
    }
    return new ResponseEntity(HttpStatus.BAD_REQUEST);
}

编辑

我使用如下所示的 Autowired 方法在 SecurityConfig 类的属性上加载用户名和密码:

@Autowired
private void initUser() {
    Administrator administrator = administratorRepository.findAdministrator();
    this.password = administrator.getPassword();
    this.username = administrator.getUsername();

}

我的类定义如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private static final String ADMIN_ROLE = "ADMIN";

private String username;
private String password;

@Autowired
private PasswordEncoder passwordEncoder;

@Autowired
private AdministratorRepository administratorRepository;

passwordencoder 是我用来对管理密码进行加盐和哈希处理的类,存储库是我保存数据的地方

最佳答案

使用 CustomUserDetailService 而不是像这样的 AuthenticationProvider

@Component("userDetailsService")
public class CustomUserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {


    private static String username;
    private static String password;
    private final Logger log = LoggerFactory.getLogger(CustomUserDetailsService.class);

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {



        return new User(CustomUserDetailsService.username,CustomUserDetailsService.password,null);
    }

}


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {


    @Inject
    @Qualifier("userDetailsService")
    private UserDetailsService userDetailsService;

    @Inject
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .userDetailsService(userDetailsService);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {

    }

}

然后在

中更改密码
public ResponseEntity updatePassword(Password password) {
    Administrator administrator = administratorRepository.findAdministrator();
    if (passwordEncoder.matches(password.getOldPassword(), administrator.getPassword())) {
        String encodePassword = passwordEncoder.encode(password.getNewPassword());
        administrator.setPassword(encodePassword);
        administratorRepository.updateAdministrator(administrator);
        CustomUserDetailsService.password=encodePassword;
        return new ResponseEntity(HttpStatus.OK);
    }
    return new ResponseEntity(HttpStatus.BAD_REQUEST);
}

关于java - Spring security 动态授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42937932/

相关文章:

java - 如何在java Enum类中存储Flex文本框值?

java - spring 3子bean验证

Spring MVC : Not able to submit form data in JSON format

java - 如何从MySql表列中检索特定字段的总和到变量中

java - 无间距的 SWT 布局允许水平填充给定的小部件

Java速度和内存占用 "contest"

java - bean实例化失败;嵌套异常是 org.springframework.beans.BeanInstantiationException :

java - Eclipse - 如何仅对特定文件夹而不是整个项目设置 javadoc 警告

spring - SFTP 出站网关不工作

java - 在 spring mvc 中,如何使用@RequestMapping 链接到另一个 jsp?