Giter VIP home page Giter VIP logo

spring-webflux-security-jwt's Issues

How to use this application

Sorry I am new to this whole Spring Security scenario, and also to reactive programming. I am trying to run this application, and I am not sure how I can login to this application and generate the JWT Token for furthur requests to the resource server

Missing @EnableReactiveMethodSecurity

First off thank you for this great example.

I think you forgot to add the @EnableReactiveMethodSecurity annotation on your SecuredRestApplication. I was playing around a bit with your code and removing the ADMIN role from the user setup did not prevent me from accessing the /api/admin endpoint.

@Bean
public MapReactiveUserDetailsService userDetailsRepository() {
	UserDetails user = User.withDefaultPasswordEncoder()
	                       .username("user")
	                       .password("user")
	                       .roles("USER")
	                       .build();
	return new MapReactiveUserDetailsService(user);
}

Then I generated a new token Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwicm9sZXMiOiJST0xFX1VTRVIiLCJpc3MiOiJyYXBoYS5pbyIsImV4cCI6MTU2NzY3OTY3OX0.C67PZ_YX2Zm1_YDMnVgqoxNXCEd4iKOhTM9EdiEA5WI (content can be checked via https://jwt.io/ and verified with the default secret of your app).

This will then still allow me to call the admin endpoint:

$ http -v :8080/api/admin "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwicm9sZXMiOiJST0xFX1VTRVIiLCJpc3MiOiJyYXBoYS5pbyIsImV4cCI6MTU2NzY3OTY3OX0.C67PZ_YX2Zm1_YDMnVgqoxNXCEd4iKOhTM9EdiEA5WI"
GET /api/admin HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwicm9sZXMiOiJST0xFX1VTRVIiLCJpc3MiOiJyYXBoYS5pbyIsImV4cCI6MTU2NzY3OTY3OX0.C67PZ_YX2Zm1_YDMnVgqoxNXCEd4iKOhTM9EdiEA5WI
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/0.9.8



HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
Expires: 0
Pragma: no-cache
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
transfer-encoding: chunked

[
    {
        "message": "Hello Admin!",
        "name": "Admin"
    }
]

When adding the @EnableReactiveMethodSecurity annotation, I get the following, as expected:

HTTP/1.1 403 Forbidden
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/plain
Expires: 0
Pragma: no-cache
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
transfer-encoding: chunked

Denied

Doc not exact :) cost me 1 hour my life

Use that in another request:

$ curl -v -H "Authorization: Authorization: Bearer eyJhbGciOiJIUzI1Ni....." localhost:8080/api/admin

You should be able to consume the API


have to be:
$ curl -v -H "Authorization: Bearer eyJhbGciOiJIUzI1Ni....." localhost:8080/api/admin

Split responsibility of ServerHttpBearerAuthenticationConverter

I think ServerHttpBearerAuthenticationConverter should be used only for preparing the token for further processing:

Mono.justOrEmpty(serverWebExchange)
                .map(JWTAuthorizationPayload::extract)

while authenticating the token:

map(VerifySignedJWT::check)
                .map(UsernamePasswordAuthenticationFromJWTToken::create)

is the responsibility of JWTReactiveAuthenticationManager

By the way - instead of providing own implementation of JWTAuthorizationWebFilter just do:

@Component
public class JWTAuthenticationWebFilter extends AuthenticationWebFilter {

    public JWTAuthenticationWebFilter(final JWTAuthenticationManager authenticationManager,
            final ServerHttpBearerAuthenticationConverter converter,
            final UnauthorizedAuthenticationEntryPoint entryPoint) {
        super(authenticationManager);
        setAuthenticationConverter(converter);
        setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(entryPoint));
        setRequiresAuthenticationMatcher(new JWTHeadersExchangeMatcher()); //this is necessary to match headers. Requests without JWT header should not be taken into account by this filter
    }
    private static class JWTHeadersExchangeMatcher implements ServerWebExchangeMatcher {

        @Override
        public Mono<MatchResult> matches(final ServerWebExchange exchange) {
            return Mono.just(exchange)
                    .map(ServerWebExchange::getRequest)
                    .map(ServerHttpRequest::getHeaders)
                    .filter(h -> h.containsKey("some JWT header"))
                    .flatMap($ -> MatchResult.match())
                    .switchIfEmpty(MatchResult.notMatch());
        }
    }
}

And don't forget to set:

        http
            .exceptionHandling()
                .authenticationEntryPoint(new UnauthorizedAuthenticationEntryPoint ())
            .and()

where

@Component
public class UnauthorizedAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {

	@Override
	public Mono<Void> commence(final ServerWebExchange exchange, final AuthenticationException e) {
		return Mono.fromRunnable(() -> exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED));
	}
}

otherwise SpringSecurity will still display BasicAuth on requests without headers

AuthorizationHeaderPayload should use getResponse()?

Should AuthorizationHeaderPayload be using getResponse()?

https://github.com/raphaelDL/spring-webflux-security-jwt/blob/master/src/main/java/io/rapha/spring/reactive/security/auth/jwt/AuthorizationHeaderPayload.java#L29

`public class AuthorizationHeaderPayload {

public static Mono<String> extract(ServerWebExchange serverWebExchange) {
    return Mono.justOrEmpty(serverWebExchange.getResponse()
            .getHeaders()
            .getFirst(HttpHeaders.AUTHORIZATION));
}

}`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.