当前位置: 首页 > 知识库问答 >
问题:

角色在Spring Security中无法正常工作[重复]

姜俊友
2023-03-14

我正在开发一个基于spring security的web应用程序,我想根据登录用户的角色是ADMIN还是user来限制侧栏上的项目。就身份验证而言,一切正常,但角色没有按预期工作。

跟随这篇文章

例如-

<security:authorize access="hasRole('ADMIN')">
            <li class=" nav-item"><a href="<c:url value = "/mapview/list"/>"><i
                    class="fa fa-map-marker"></i><span class="menu-title" data-i18n="">MapView</span></a>
            </li>
            </security:authorize>

即使我以-ADMIN登录,上述元素也永远不可见。

有人能在这里帮助我理解出了什么问题吗?

安全配置

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

    @Bean
    public AuthenticationProvider authProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(new BCryptPasswordEncoder());
        return provider;
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {


        httpSecurity
                .authorizeRequests().antMatchers("/login", "/resource/**").permitAll()
                .anyRequest().fullyAuthenticated()
                .and()
                .formLogin()
                .loginPage("/login").usernameParameter("username").passwordParameter("password").permitAll()
                .loginProcessingUrl("/doLogin").successForwardUrl("/postLogin").failureUrl("/loginFailed").and()
                .logout().logoutUrl("/doLogout").logoutSuccessUrl("/logout").permitAll().and().csrf().disable();
    }


}

UserDetailsImpl

public class UserDetailsImpl implements UserDetails {

    private static final long serialVersionUID = 1L;
    private Collection<SimpleGrantedAuthority> authorities;
    private String username;
    private String password;
    private Boolean enabled = true;

    public void setAuthorities(Collection<SimpleGrantedAuthority> authorities) {
        this.authorities = authorities;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }
    @Override
    public String getPassword() {
        return password;
    }
    @Override
    public String getUsername() {
        return username;
    }
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    @Override
    public boolean isEnabled() {
        return enabled;
    }

用户详细信息服务

@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserService userService;
    private Converter<User, UserDetails> userUserDetailsConverter;

    @Autowired
    @Qualifier(value = "userToUserDetails")
    public void setUserUserDetailsConverter(Converter<User, UserDetails> userUserDetailsConverter) {
        this.userUserDetailsConverter = userUserDetailsConverter;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return userUserDetailsConverter.convert(userService.findByUserName(username));
    }
}

用户详细信息

@Component
public class UserToUserDetails implements Converter<User, UserDetails>{
     @Override
        public UserDetails convert(User user) {
            UserDetailsImpl userDetails = new UserDetailsImpl();
            if (user != null) {
                userDetails.setUsername(user.getUsername());
                userDetails.setPassword(user.getEncryptedPassword());
                userDetails.setEnabled(user.getEnabled());
                Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
                user.getRoles().forEach(role -> {
                    authorities.add(new SimpleGrantedAuthority(role.getName()));
                });
                userDetails.setAuthorities(authorities);
            }
            return userDetails;
        }
    }

控制器

@SessionAttributes({ "currentUser" })
@Controller
public class HomeController {
  //skipping other mappings
@RequestMapping(value = "/postLogin", method = RequestMethod.POST)
    public String postLogin(Model model, HttpSession session) {
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder
                .getContext().getAuthentication();
        validatePrinciple(authentication.getPrincipal());
        String username = ((UserDetailsImpl) authentication.getPrincipal()).getUsername();
        model.addAttribute("currentUser", username);
        return "redirect:/dashboard";
    }

}

使用者

@Entity
public class User extends Auditable<String> {

//skipping other details
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "user_role",
            joinColumns = { @JoinColumn(name = "user_id") },
            inverseJoinColumns = { @JoinColumn(name = "role_id") })
    private Set<Role> roles = new HashSet<>();

}

在db中创建的表-

user
role
user_role

编辑1

刚刚在我的控制器中添加了这个映射,一旦我登录,如果我在浏览器上点击/测试,两个布尔值都会显示false。我不知道为什么没有设定角色-(

@GetMapping(value = "/test")
    public void test(SecurityContextHolderAwareRequestWrapper request) {
        boolean b = request.isUserInRole("ADMIN");
        System.out.println("ROLE_ADMIN=" + b);

        boolean c = request.isUserInRole("USER");
        System.out.println("ROLE_USER=" + c);
    }

编辑2

但同时,下面的代码显示了管理员的角色

public void test(SecurityContextHolderAwareRequestWrapper request) {

        for (GrantedAuthority authority : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) {
            String userRole = authority.getAuthority();
            System.out.println(userRole);
        }
    }

共有1个答案

夏元明
2023-03-14

这看起来像是从数据库中检索信息和向浏览器返回响应之间的某个地方丢失了信息(显然)。幸好您有一个调试器,所以我会从访问数据库数据的每个步骤开始跟踪,直到返回该信息。遵循每一步,直到你找到它丢失的地方,当你把它缩小到一个单一的地方后再发回来。如果没有,也许我们可以开始查看您的html/脚本/模板引擎,但只有在我们确定信息到达浏览器之后。

 类似资料:
  • 我正在尝试用Spring Boot学习Spring Security性。我有一个我正在实现它的演示。它适用于登录页面和配置文件方法,可以由任何有效用户进行身份验证。但当我试图访问某个特定角色时,它不起作用,并给我一个“403-拒绝访问”。 我的接入点 我的配置方法 我的角色分配

  • 问题内容: 尽管我很确定这是昨天或前一天工作的,例如,在IE10中不再起作用。我已经测试了我的浏览器,但是它不再起作用了。还有谁有相同的问题吗?或者,它永远都行不通吗? 问题答案: IE不支持输入type =“ number”,但您可以使用jQueryUISpinner小部件。它非常易于使用,并且具有许多对开发人员友好的API。

  • 问题内容: 这正是我想要做的 我用表格打开一个页面,该表格包含有关用户的信息 我的getText()元素指示表中的用户数(例如“列表中的11个用户”) 我删除“列表中的用户”部分,并将字符串转换为整数,以便稍后在for循环中使用 我需要通过用户名(第9列)查找某些用户,并获取数字,该数字是该用户信息所在的行数(这就是我被卡住的地方) 我转到该行的第一列(该行将成为该特定用户的编辑按钮),然后单击它

  • 问题内容: 工作如何? 以下代码在这里不起作用: Employee.java 地址.java persistence.xml 这是测试类……请检查城市名称,它没有在ADDRESS表中按降序存储地址值 JPAOrderByAnnotationTest 问题答案: 我认为您误解了注释的实际作用。根据javadoc: 指定在 检索 关联或集合时,将值指定为关联的集合或元素集合的元素的顺序。 [添加重点]

  • 我这里有点麻烦。我试图在我的MVC4项目中使用TinyMCE作为文本编辑器。 到目前为止,这很简单,我只需要能够正确地显示编辑器。 我有两个重要的类。 控制员: 然后是视图,这就是我试图让TinyMCE工作的地方: @{ViewBag.Title=“Index”;} 亲善 这是一些可以用TinyMCE编辑的内容。 出于某种原因,结果是这样的:它看起来如何 知道为什么我没有从TinyMCE获得任何功

  • 问题内容: 我已经建立了俄罗斯方块游戏。现在,我已经使用JPanel来显示内容和块(使用paintComponents()方法)。 问题是,当我尝试从另一个JFrame调用tetris程序时,它根本无法绘制。 我的俄罗斯方块主菜单的代码是: 当调用MatrixBoard的构造函数时,俄罗斯方块游戏会在新窗口中开始。但是,这些块在屏幕上不可见。MatrixBoard的代码是: 请帮忙。我怀疑问题出在