spring security国际化及UserCache的配置和使用

yizhihongxing
  1. Spring Security国际化配置:

要实现Spring Security的国际化,需要进行以下配置:

(1)在Spring Security的配置文件中增加MessageSourceBean的配置,并将其注入到Spring Security的配置中:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MessageSource messageSource;

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasenames("classpath:messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/home")
            .permitAll()
            .and()
            .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login?logout")
            .permitAll()
            .and()
            .exceptionHandling()
            .accessDeniedPage("/403")
            .and()
            .csrf().disable();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/webjars/**","/css/**","/js/**");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user")
            .password("{noop}password")
            .roles("USER");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("language");
        registry.addInterceptor(localeChangeInterceptor);
    }

    @Bean
    public LocaleResolver localeResolver() {
        CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
        cookieLocaleResolver.setDefaultLocale(Locale.ENGLISH);
        cookieLocaleResolver.setCookieName("language");
        cookieLocaleResolver.setCookieMaxAge(3600);
        return cookieLocaleResolver;
    }

    @Bean
    public AuthenticationSuccessHandler authenticationSuccessHandler() {
        SavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        authenticationSuccessHandler.setTargetUrlParameter("targetUrl");
        return authenticationSuccessHandler;
    }

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        SimpleUrlAuthenticationFailureHandler authenticationFailureHandler = new SimpleUrlAuthenticationFailureHandler();
        authenticationFailureHandler.setUseForward(true);
        authenticationFailureHandler.setDefaultFailureUrl("/login?error");
        return authenticationFailureHandler;
    }
}

(2)在项目的资源文件中增加messages.properties和messages_zh_CN.properties两个文件,分别用于英语和中文语言环境的国际化支持。

messages.properties

login.title=Login Page
login.username=Username
login.password=Password
login.signIn=Sign in
login.language=Language
home.title=Home Page
home.welcome=Welcome, {0}!
403.title=Access Denied
403.message=Sorry, you do not have permission to access this page.

messages_zh_CN.properties

login.title=登录页
login.username=用户名
login.password=密码
login.signIn=登录
login.language=语言
home.title=主页
home.welcome=欢迎,{0}!
403.title=拒绝访问
403.message=对不起,你没有权限访问这个页面。

(3)在页面中添加语言环境的切换按钮,并实现其功能,即控制语言环境参数的传递。

<div class="language-switch">
    <a href="?language=en">English</a>
    <span>|</span>
    <a href="?language=zh_CN">中文</a>
</div>
  1. UserCache的配置和使用:

UserCache主要用于在一个会话中缓存用户信息,主要配置如下:

(1)在Spring Security的配置文件中增加UserCacheBean的配置,并将其注入到Spring Security的配置中:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserCache userCache;

    @Bean
    public UserCache userCache() {
        return new HttpSessionUserCache();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/home")
            .successHandler(authenticationSuccessHandler())
            .failureHandler(authenticationFailureHandler())
            .permitAll()
            .and()
            .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login?logout")
            .permitAll()
            .and()
            .exceptionHandling()
            .accessDeniedPage("/403")
            .and()
            .csrf().disable();
    }
}

(2)在登录成功后,通过UserCache缓存用户信息:

@Service
public class AuthenticationUserDetailsService implements UserDetailsService {

    @Autowired
    private UserCache userCache;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 查数据库获取用户信息
        User user = userService.getUserByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        String password = user.getPassword();
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        UserDetails userDetails = new User(username, password, authorities);
        userCache.putUserInCache(userDetails);
        return userDetails;
    }
}

(3)在需要使用UserCache缓存的地方,通过UserCache获取缓存的用户信息:

@Controller
public class HomeController {

    @Autowired
    private UserCache userCache;

    @GetMapping("/home")
    public String home(Model model) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        UserDetails userDetails = userCache.getUserFromCache(username);
        String welcomeMessage = messageSource().getMessage("home.welcome", new Object[]{userDetails.getUsername()}, LocaleContextHolder.getLocale());
        model.addAttribute("welcomeMessage", welcomeMessage);
        return "home";
    }
}

在以上代码中,我们通过UserCache缓存登录成功后的用户信息,在HomeController中的home方法中,通过UserCache获取缓存的用户信息,然后从国际化的资源文件中获取欢迎信息,并添加到model中。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring security国际化及UserCache的配置和使用 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • JSP XMLHttpRequest动态无刷新及其中文乱码处理

    JSP XMLHttpRequest动态无刷新及其中文乱码处理,是前端开发中经常会遇到的问题之一。下面,我们将介绍一些方法来解决这个问题。 1. JSP动态无刷新 实现动态无刷新需要使用XMLHttpRequest对象。XMLHttpRequest对象被用于在web浏览器和web服务器之间传输数据。JSP实现动态无刷新的步骤一般如下: 步骤1:创建XMLHt…

    Java 2023年6月15日
    00
  • SpringBoot Bean花式注解方法示例下篇

    请听我详细讲解“SpringBoot Bean花式注解方法示例下篇”的完整攻略。 概述 本文主要介绍在Spring Boot项目中常用的Bean注解及其用法,包括@Component、@Service、@Repository、@Controller、@Configuration、@Bean等。 @Component注解 @Component是最常用的注解之一…

    Java 2023年6月3日
    00
  • Java实现顺序栈的示例代码

    下面是Java实现顺序栈的示例代码的完整攻略。 什么是顺序栈 顺序栈是一种使用数组实现的栈,也称作数组栈。其基本特点是后进先出,即最后进栈的元素最先出栈。 顺序栈的实现思路 顺序栈需要使用数组保存元素,因此先声明一个数组; 定义一个变量top表示栈顶元素的下标,初始值为-1; 入栈操作时,将元素插入到数组中,top的值加1; 出栈操作时,将栈顶元素弹出,to…

    Java 2023年5月19日
    00
  • LINQ教程之使用Lambda表达式

    很高兴为您讲解“LINQ教程之使用Lambda表达式”的完整攻略。 什么是Lambda表达式 Lambda表达式源于函数式编程,是一种简洁的表达方式。在C#中,Lambda表达式被用来编写LINQ查询、事件处理程序、委托等。 Lambda表达式的格式如下: (argument-list) => expression 其中,argument-list 是…

    Java 2023年5月19日
    00
  • 基于Java回顾之JDBC的使用详解

    基于Java回顾之JDBC的使用详解 1. 什么是JDBC JDBC是Java DataBase Connectivity的缩写,它是用于Java语言操作关系型数据库的应用程序接口(API)。JDBC提供了一种标准的方法,用于连接和操作各种类型的关系型数据库。 JDBC规范定义了一套Java类库,通过这些类库,我们可以在Java程序中使用SQL命令执行各种数…

    Java 2023年5月19日
    00
  • java的Hibernate框架报错“ConnectionException”的原因和解决方法

    当使用Java的Hibernate框架时,可能会遇到“ConnectionException”错误。这个错误通常是由于以下原因之一引起的: 数据库连接失败:如果您的数据库连接失败,则可能会出现此错误。在这种情况下,需要检查您的数据库连接以解决此问题。 数据库访问权限不足:如果您的数据库访问权限不足,则可能会出现此错误。在这种情况下,需要检查您的数据库访问权限…

    Java 2023年5月4日
    00
  • JavaSpringBoot报错“TransactionTimedOutException”的原因和处理方法

    当使用Java的Spring Boot框架时,可能会遇到“TransactionTimedOutException”错误。这个错误通常是由以下原因之一引起的: 事务超时:如果事务执行时间超过了设置的超时时间,则可能会出现此错误。在这种情况下,需要增加超时时间或优化事务执行时间。 数据库锁:如果在事务执行期间出现了数据库锁,则可能会出现此错误。在这种情况下,需…

    Java 2023年5月5日
    00
  • java的时间类汇总(齐全)

    Java的时间类汇总(齐全): Java是一门强大的编程语言,其中时间类也是其核心组成部分之一。在Java中,时间类主要分为以下几种: 1. java.util包中的Date类 Date类是Java中最基础的时间类。它代表时间和日期的基本构建块,可以表示从1970年1月1日的00:00:00 GMT开始的时间。Date类可以处理的时间范围是公元前 337年 …

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部