team-learn-programming-yourself / jwt-youtube

58 stars 58 forks source link

This implementation follows bad practices. #2

Open Toerktumlare opened 2 years ago

Toerktumlare commented 2 years ago

This entire repo is explaining bad practices. this is NOT how you implement the handling of JWTs in spring security. Spring security has had full JWT support since 2018.

Writing custom filters and custom handling of JWTs is bad practice, because if you write something wrong, the entire applications data could be compromised.

This tutorial doesn't follow a single standard of how the handling of JWTs are implemented in the spring security reference manual. This just a single developers homemade poor solution and should be deleted.

This is how you implement it correctly https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html

And here is an official simple example from spring security https://github.com/spring-projects/spring-security/blob/5.4.x/samples/boot/oauth2resourceserver-jwe/src/main/java/sample/OAuth2ResourceServerSecurityConfiguration.java

This entire repo should be eiter deleted, or rewritten to follow best practices and follows the implementations of the spring security reference manual.

rudrakshya commented 2 years ago

Can you be more specific what you see wrong in this repository? Every Instructor's tutorial in Youtube, Udemy and elsewhere teach almost the same way. If you think the whole code repository follow the bad practice, can you explain your own, rather than just blaming. And your spring link is not so good for everyone to learn things quickly. It takes a lot of time and hassle to learn a simple thing from docs.

Toerktumlare commented 2 years ago

Well there is your problem. Every Instructor's tutorial in Youtube, Udemy and elsewhere teach almost the same way

this is because everyone reasons like you, "it takes too much time to read the official documentation". Well you need to put in the work.

Spring security released with spring security 5 full jwt support, meaning that spring comes shipped with oauth2 filter, that can by ease be configured to instead handle jwts.

Taken from the documentation right here:

protected void configure(HttpSecurity http) {
    http
        .authorizeHttpRequests(authorize -> authorize
            .anyRequest().authenticated()
        )
        .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
}

This is how you enable the jwt filter if you wish to customise it. Thats all the code you need. Im basically saying, this is now a resource server, that now accepts jwts.

To decode the jwt, all you do is to use the already built in Nimbus library that comes shipped with Spring Security, no need to pull in something external at all. And all you do using the builder pattern is to provide a decoder as a bean which is shown here in the docs.

@Bean
public JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
}

If you want to extract authorities from your jwt all you do is add another bean as shown here

// for instance convert claims to roles
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
    grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");

    JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
    jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
    return jwtAuthenticationConverter;
}

You want me to be more specific? Most of the code written is faulty since nothing in the implementation follows anything from the spring security reference. Its very clear that you havn't even looked in the reference.

Some other notes in general:

This entirre repository is teaching people how to use jwts basically as session token. You login someone, issue them a jwt, and then provide the jwt in a request, and login the person using the jwt.

there are several blog posts out there that all explain why jwts should not be used as jwts:

Redis points out it is bad: https://redis.com/blog/json-web-tokens-jwt-are-dangerous-for-user-sessions/

Okta points out that this is bad: https://developer.okta.com/blog/2017/08/17/why-jwts-suck-as-session-tokens

Dzone has pointed this out: https://dzone.com/articles/stop-using-jwts-as-session-tokens

It was even pointed out over 7 years ago that this is bad http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/

There are several usercases where jwts are a vlid option, but using them as a session token is not one of them.

And also, writing blog post/youtube video and claim its valid because "everyone else does it" is not a vlid argument. Would you jump off a cliff if everyone else does it? No, if you do a youtube video or a blog post, you should always read up on what is stated is the best practice. And you do that by doing research and you read the official guidelines and manual.

Spring wrote spring security, which means your facts should come from the developers, not proxied by someone else.

Saying that "the manual is too hard" is just an excuse for not putting in the time and effort.

If you find the manual too hard, i suggest you start reading here:

The Architecture of Spring Security

So that you understand the basic building blocks of spring security. After you read that section, you will understand all the other sections more easy.