将属性传递给Spring Security应用程序中的视图

时间:2014-07-03 18:12:03

标签: java spring spring-mvc spring-security

在我的spring应用程序中,登录过程由Spring Security使用UserDetailsS​​ervice和BCryptPassword类处理。登录成功后,该类将使用重定向到主页:

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth) throws IOException, ServletException {
        HttpSession session = request.getSession();
        SavedRequest savedReq = (SavedRequest) session.getAttribute(WebAttributes.ACCESS_DENIED_403);

        if (savedReq == null) {
            response.sendRedirect(request.getContextPath() + "/acesso/home");
        }
        else {
            response.sendRedirect(request.getContextPath() + "/acesso/login?erro=no_permit");
        }
    }

}

在jsp页面中,我可以使用以下表达式获取用户名:

${pageContext.request.remoteUser}

但是,在我的数据库中,我还存储了名字和姓氏。我需要在上面的课程中(或在任何可能的地方)将这些数据传递给我的视图。我试试这个:

request.getSession().setAttribute("username", "Usuario Teste");

在视图中使用它:${username},但是当我运行应用程序时,没有显示任何内容。

任何人都可以指出我这样做的方法吗?

我的春季安全配置

protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf()
            .disable()
        .authorizeRequests()
            .antMatchers("/resources/**", "/publico/**").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/acesso/login").permitAll()
            .loginProcessingUrl("/login").permitAll()
            .usernameParameter("login")
            .passwordParameter("senha")
            .successHandler(new CustomAuthenticationSuccessHandler())
            .failureHandler(new CustomAuthenticationFailureHandler())
            .and()
        .exceptionHandling()
            .accessDeniedHandler(new CustomAccessDeniedHandler())
            .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/acesso/login").permitAll();
}

更新

身份验证提供程序

public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserDetailsService usuario;

    @Autowired
    private BCryptPasswordEncoder encoder;

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

        UserDetails user = usuario.loadUserByUsername(name);

        if(encoder.matches(user.getPassword(), password)) {
            Authentication auth = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), user.getAuthorities());
            return auth;
        }
        else {
            return null;
        }
    }

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

}

的UserDetailsS​​ervice

@Service
public class AcessoService implements UserDetailsService {

    @Autowired
    private UsuarioHome accountDao;

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Usuario account = accountDao.findByField("login", username);

        if(account==null) {
            System.out.println("No such user: " + username);
            throw new UsernameNotFoundException("No such user: " + username);
        } else if (account.getAutorizacao().isEmpty()) {
            System.out.println("User " + username + " has no authorities");
            throw new UsernameNotFoundException("User " + username + " has no authorities");
        }

        List<Permissao> lista = new ArrayList<Permissao>();
        int max = account.getAutorizacao().size();
        for(int i=0; i<max; i++) {
            int max2 = account.getAutorizacao().get(i).getPermissao().size();
            for(int j=0; j<max2; j++) {
                lista.add(account.getAutorizacao().get(i).getPermissao().get(j));
            }
        }

        boolean accountIsEnabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

        return new User(account.getLogin(), account.getSenha(), accountIsEnabled, accountNonExpired, credentialsNonExpired, accountNonLocked, getAuthorities(lista));
    }

    public List<String> getRolesAsList(List<Permissao> list) {
        List <String> rolesAsList = new ArrayList<String>();
        for(Permissao role : list){
            rolesAsList.add(role.getNome());
        }
        return rolesAsList;
    }

    public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        return authorities;
    }

    public Collection<? extends GrantedAuthority> getAuthorities(List<Permissao> list) {
        List<GrantedAuthority> authList = getGrantedAuthorities(getRolesAsList(list));
        return authList;
    }

}

1 个答案:

答案 0 :(得分:1)

您正在存储&#34;用户名&#34;会议中的数据。

您可以尝试通过以下两种方式之一来获取它。

request.setAttribute("username", "Usuario Teste");然后你可以直接使用$ {username} EL。或者您可以将request.getSession().setAttribute("username", "Usuario Teste");与$ {sessionScope.username} EL。

一起使用

您必须知道会话和请求范围之间的差异。

PD: 阅读this

另一方面,要获得Spring Sec中的用户名,可以尝试使用<sec:authentication property="principal.username" />

并且,如果您想使用比一个String更复杂的对象作为主体,则可以扩展UsernamePasswordAuthenticationToken。