Vaadin 21 查看角色

Posted

技术标签:

【中文标题】Vaadin 21 查看角色【英文标题】:Vaadin 21 View Roles 【发布时间】:2021-12-24 15:37:09 【问题描述】:

我想将我的 Vaadin 应用程序重写为 Vaadin 21。 我使用 Vaadin 入门构建器 (https://vaadin.com/start) 创建了一个简单的应用程序。 目前我的主要斗争是将我的简单CustomAuthenticationProvider 应用于安全管理器,以便能够使用@RolesAllowed( "user", "admin","USER") 注释。

我的 AuthToken 是在其他地方生成的主要问题... 它在某处生成一个空的授权权限并忽略我的自定义 AuthProvider 代码。

问题: 如何很好地处理基于角色的访问控制?

哪里可以正确使用这个注解:

@RolesAllowed( "user", "admin","USER")
public class ProfileView extends VerticalLayout 

登录后的控制台:

UsernamePasswordAuthenticationToken [Principal=c.farkas, Credentials=[PROTECTED], Authenticated=false, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=DDE103F559B2F64B917753636B800564], Granted Authorities=[]]
xxx[USERcica, admin, USER]
??UsernamePasswordAuthenticationToken [Principal=c.farkas, Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[USERcica, admin, USER]]

SecurityConfiguration.java

@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurityConfigurerAdapter 

    @Autowired
    private RequestUtil requestUtil;

    @Autowired
    private VaadinDefaultRequestCache vaadinDefaultRequestCache;
    
    @Autowired
    private ViewAccessChecker viewAccessChecker;
    
    @Autowired
    CustomAuthenticationProvider customAuthenticationProvider;



    public static final String LOGOUT_URL = "/";

    @Bean
    public PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 

//      super.configure(http);

        http.csrf().ignoringRequestMatchers(requestUtil::isFrameworkInternalRequest);
        // nor with endpoints
        http.csrf().ignoringRequestMatchers(requestUtil::isEndpointRequest);

        // Ensure automated requests to e.g. closing push channels, service
        // workers,
        // endpoints are not counted as valid targets to redirect user to on
        // login
        http.requestCache().requestCache(vaadinDefaultRequestCache);

        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry urlRegistry = http
                .authorizeRequests();
        // Vaadin internal requests must always be allowed to allow public Flow
        // pages
        // and/or login page implemented using Flow.
        urlRegistry.requestMatchers(requestUtil::isFrameworkInternalRequest).permitAll();
        // Public endpoints are OK to access
        urlRegistry.requestMatchers(requestUtil::isAnonymousEndpoint).permitAll();
        // Public routes are OK to access
        urlRegistry.requestMatchers(requestUtil::isAnonymousRoute).permitAll();
        urlRegistry.requestMatchers(getDefaultHttpSecurityPermitMatcher()).permitAll();

        // all other requests require authentication
        urlRegistry.anyRequest().authenticated();

        // Enable view access control
        viewAccessChecker.enable();

        setLoginView(http, LoginView.class, LOGOUT_URL);
    
    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        // Custom authentication provider - Order 1
        auth.authenticationProvider(customAuthenticationProvider);

        // Built-in authentication provider - Order 2
    /*  auth.inMemoryAuthentication().withUser("admin").password("noopadmin@password")
                // noop makes sure that the password encoder doesn't do anything
                .roles("ADMIN") // Role of the user
                .and().withUser("user").password("noopuser@password").credentialsExpired(true).accountExpired(true)
                .accountLocked(true).roles("USER");*/
    

    @Override
    public void configure(WebSecurity web) throws Exception 
        super.configure(web);
        web.ignoring().antMatchers("/images/*.png");
    

CustomAuthenticationProvider.java

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider 

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException 
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        System.out.println(authentication);

        try 
//          LdapContext ldapContext = 
            ActiveDirectory.getConnection(username, password);
            List<GrantedAuthority> authorityList = new ArrayList<GrantedAuthority>();

            authorityList.add(new SimpleGrantedAuthority("USER" + "cica"));

            authorityList.add(new SimpleGrantedAuthority("admin"));
            authorityList.add(new SimpleGrantedAuthority("USER"));
            
            System.out.println("xxx"+authorityList.toString());

            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                    username, password, authorityList);

            System.out.println("??" + usernamePasswordAuthenticationToken);

            String id = VaadinSession.getCurrent() != null ? VaadinSession.getCurrent().getSession().getId() : "";
            return usernamePasswordAuthenticationToken;
         catch (NamingException e) 
//          e.printStackTrace();
//          throw new CortexException("Authentication failed");
            throw new BadCredentialsException("Authentication failed");
        

    

    @Override
    public boolean supports(Class<?> aClass) 
        return aClass.equals(UsernamePasswordAuthenticationToken.class);
    

【问题讨论】:

【参考方案1】:

您必须添加 ROLE_ 前缀来告诉 Spring Security GrantedAuthority 是角色类型。

authorityList.add(new SimpleGrantedAuthority("ROLE_USER" + "cica"));
authorityList.add(new SimpleGrantedAuthority("ROLE_admin"));
authorityList.add(new SimpleGrantedAuthority("ROLE_USER"));

【讨论】:

我感到很惭愧 :( 我之前的代码被硬编码为将 ROLE_ 添加到所有 AD 组,但我只是忘记复制了。

以上是关于Vaadin 21 查看角色的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Apache Shiro 处理分层角色/权限?

如何在 Vaadin 应用程序中使用单点登录

PHP.46-TP框架商城应用实例-后台21-权限管理-权限和角色的关系

如何查看oracle用户具有的权限和角色

如何查看oracle用户具有的权限和角色?

oracle创建,查看用户和角色,用户角色赋权