简体   繁体   中英

Spring boot JWT cannot authorized rest api

I am trying to implement JWT on my Spring Boot 2 project.

my reference link https://www.callicoder.com/spring-boot-spring-security-jwt-mysql-react-app-part-2/

My Securityconfig file is

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
        prePostEnabled=true,
        jsr250Enabled = true,
        securedEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private Environment env;

    @Autowired
    private UserSecurityService userSecurityService;


    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }



    private BCryptPasswordEncoder passwordEncoder() {
        return SecurityUtils.passwordEncoder();
    }


    @Autowired
    private SecurityHandler securityHandler;


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

        http
            .authorizeRequests()

        /*  antMatchers("/**").*/
            .antMatchers(PUBLIC_MATCHERS).
            permitAll().anyRequest().authenticated();

        http
                .cors()
                .and()
                .csrf()
                .disable()
                .exceptionHandling()
                .authenticationEntryPoint(unauthorizedHandler)
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/",
                        "/favicon.ico",
                        "/**/*.png",
                        "/**/*.gif",
                        "/**/*.svg",
                        "/**/*.jpg",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js","/login",
                        "/api/auth/signin")
                .permitAll()
                .antMatchers("/api/auth/**")
                .permitAll()
                .antMatchers("/api/user/checkUsernameAvailability", "/api/user/checkEmailAvailability")
                .permitAll()
                .antMatchers(HttpMethod.GET, "/api/polls/**", "/api/users/**")
                .permitAll()
                .anyRequest()
                .authenticated();


        // Add our custom JWT security filter
        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
    }

    @Bean(BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Override
    public void configure(WebSecurity web) throws  Exception{
        web.ignoring()
                .antMatchers("/api/updateCardStatus","/api/login","*/uploads/***","/api/getUsersDetail","/api/getStudentDetails","/api/getAccountLoad","/api/issueDirectives","/api/changePassword","/api/cardActivation","/api/CustomerAccountCardDetails","/api/accountLoad","/api/updateConsumersProfile","/api/verifyCvv"
                        ,"/api/updatePrepaidCardStatus","/api/getStatementData");
    }

}

My User class

@Entity
public class User  {


    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id", nullable = false, updatable = false)
    private Long id;

    private String username;
    private String password;
    private String userType;
    private boolean enabled=true;

    @OneToOne(mappedBy = "user")
    private BankUserDetails bankUserDetails;

    @OneToOne(mappedBy = "user")
    private SctUserDetails sctUserDetails;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JsonIgnore
    private List<UserRole> userRoles = new ArrayList<>();
}

UserRole.java

@Entity
@Table(name="user_role")
public class UserRole {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long userRoleId;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="user_id")
    private User user;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="role_id")
    private Role role;

}

Role.java

@Entity
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int roleId;
    private String name;

    @OneToMany(mappedBy = "role", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
    private List<UserRole> userRoles = new ArrayList<>();

    public int getRoleId() {
        return roleId;
    }

    public void setRoleId(int roleId) {
        this.roleId = roleId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<UserRole> getUserRoles() {
        return userRoles;
    }

    public void setUserRoles(List<UserRole> userRoles) {
        this.userRoles = userRoles;
    }
}

UserPrincipal.java

public class UserPrincipal implements UserDetails {
    private Long id;

    private String username;
    private String password;
    private String userType;
    private boolean enabled=true;


    @JsonIgnore
    private static List<UserRole> userRoles = new ArrayList<>();

    private Collection<? extends GrantedAuthority> authorities;

    public UserPrincipal(Long id,  String username,  String password, Collection<? extends GrantedAuthority> authorities) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.authorities = authorities;
    }

    public static UserPrincipal create(User user) {
/*        List<GrantedAuthority> authorities = user.getRoles().stream().map(role ->
                new SimpleGrantedAuthority(role.getName().name())
        ).collect(Collectors.toList());*/

            List<GrantedAuthority> authorites = new ArrayList<>();
            userRoles.forEach(ur -> authorites.add(new Authority(ur.getRole().getName())));


        return new UserPrincipal(
                user.getId(),
                user.getUsername(),
                user.getPassword(),
                authorites
        );
    }


    public Long getId() {
        return id;
    }


    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserPrincipal that = (UserPrincipal) o;
        return Objects.equals(id, that.id);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id);
    }
}

now when i try to call http://localhost:5060/token/generate-token from postman i get the response

{
    "timestamp": "2018-09-05T09:15:09.797+0000",
    "status": 401,
    "error": "Unauthorized",
    "message": "Sorry, You're not authorized to access this resource.",
    "path": "/token/generate-token"
}

now i think this is because i am unable to get thre required authorities.

since my entities are different than the entities given in the example i guess i am unable to acquire the fully authenticated user object. i might be wrong but can someone help me point out the exact problem ?

You have to do three main steps to test this sample. First of all you have to insert some roles in role table. After that you have to register a user to the application. Finally you can signin.

This messages means you didn't register this user.

This sample is little complicate because some different things present together, you can find the simple example for this in this URL:

http://www.jndanial.com/54

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM