Giter Site home page Giter Site logo

szerhusenbc / jwt-spring-security-demo Goto Github PK

View Code? Open in Web Editor NEW
3.0K 174.0 1.3K 328 KB

A demo for using JWT (Json Web Token) with Spring Security and Spring Boot 2

License: MIT License

Java 80.29% HTML 8.71% JavaScript 10.49% Dockerfile 0.51%
jwt jwt-authentication spring-security spring-boot java demo authentication springframework

jwt-spring-security-demo's Introduction

JWT Spring Security Demo

Screenshot from running application

About

This is a demo for using JWT (JSON Web Token) with Spring Security and Spring Boot. I completely rewrote my first version. Now this solution is based on the code base from the JHipster Project. I tried to extract the minimal configuration and classes that are needed for JWT-Authentication and did some changes.

Build Status

Requirements

This demo is build with with Maven 3.6.x and Java 11.

Usage

Just start the application with the Spring Boot maven plugin (mvn spring-boot:run). The application is running at http://localhost:8080.

You can use the H2-Console for exploring the database under http://localhost:8080/h2-console:

Screenshot from h2-console login

Backend

There are three user accounts present to demonstrate the different levels of access to the endpoints in the API and the different authorization exceptions:

Admin - admin:admin
User - user:password
Disabled - disabled:password (this user is deactivated)

There are four endpoints that are reasonable for the demo:

/api/authenticate - authentication endpoint with unrestricted access
/api/user - returns detail information for an authenticated user (a valid JWT token must be present in the request header)
/api/persons - an example endpoint that is restricted to authorized users with the authority 'ROLE_USER' (a valid JWT token must be present in the request header)
/api/hiddenmessage - an example endpoint that is restricted to authorized users with the authority 'ROLE_ADMIN' (a valid JWT token must be present in the request header)

Frontend

I've written a small Javascript client and put some comments in the code that hopefully makes this demo understandable. You can find it at /src/main/resources/static/js/client.js.

Generating password hashes for new users

I'm using bcrypt to encode passwords. Your can generate your hashes with this simple tool: Bcrypt Generator

Using another database

Actually this demo is using an embedded H2 database that is automatically configured by Spring Boot. If you want to connect to another database you have to specify the connection in the application.yml in the resource directory. Here is an example for a MySQL DB:

spring:
  jpa:
    hibernate:
      # possible values: validate | update | create | create-drop
      ddl-auto: create-drop
  datasource:
    url: jdbc:mysql://localhost/myDatabase
    username: myUser
    password: myPassword
    driver-class-name: com.mysql.jdbc.Driver

Hint: For other databases like MySQL sequences don't work for ID generation. So you have to change the GenerationType in the entity beans to 'AUTO' or 'IDENTITY'.

You can find a reference of all application properties here.

Using Flyway

#81

Docker

This project has a docker image. You can find it at https://hub.docker.com/r/hubae/jwt-spring-security-demo/.

Questions

If you have project related questions please take a look at the past questions or create a new ticket with your question.

If you have questions that are not directly related to this project (e.g. common questions to the Spring Framework or Spring Security etc.) please search the web or look at Stackoverflow.

Sorry for that but I'm very busy right now and don't have much time.

Interesting projects

Author

Stephan Zerhusen

Copyright and license

The code is released under the MIT license.


Please feel free to send me some feedback or questions!

jwt-spring-security-demo's People

Contributors

brunocleite avatar chanmyung avatar islamazab avatar komalkadam avatar lastmind4 avatar rawsanj avatar senjin-hajrulahovic avatar sivakumar-raja avatar szerhusenbc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jwt-spring-security-demo's Issues

Why is there both a User and JwtUser class?

Firstly thank you for sharing this - i finally managed to implement a working Spring Security + JTW looking at your project here!

I am not sure i understand why these 2 classes exists in the project and why the loadUserByUsername() method in JwtUserDetailsServiceImpl is not just returning a custom user class that implements UserDetails?

I changed my own implementation to this:

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    return repo.findByUsername(username);
}

where in my case the repo returns a UserAccount which implements UserDetails and the above works.

This is purely a question to try and understand the differences between the 2 implementations.

thanks -

How to implement a microservices architecture using this aproach without Oauth?

I've heard about microservices using oauth2, but for me it's really hard to learn oauth2, I mean, I understood the Oauth2 architecture but in a theorical aproach, in practice it seems to be more dificult. A lot of configuration I think, maybe for huge project. It is enough for me a lot of configuratoin using spring security that I just learn basics before.

Why not configure this project as a common or generic project that you just have to import in your pom or gradle config?

So the developers wont have to care about how to implement JWT, just extend user entity or authority entity, and changes configuration about JWT in file, and provieed a datasource only.

Something like a "spring-boot-starter-jwt"

How to configure with non-primary JPA Entity Manager

Hi Stephan, I am trying to incorporate your example into an existing spring boot application to secure some REST services. I have set up 2 separate persistence contexts, one for the application (primary) and one for the spring security from this project.
I am getting an error when I run a unit test saying that it could not instantiate a bean because it can't find the primary entity manager.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'openEntityManagerInViewInterceptor'
defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration$JpaWebConfiguration$JpaWebMvcConfiguration.class]:
Initialization of bean failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'javax.persistence.EntityManagerFactory' available: more than one 'primary' bean found among
candidates: [entityManagerFactory, entityManagerFactorySecurity]

As of right now I have both defined as primary but once I define the main app context as primary, I am afraid the security will not work or attempt to access the main persistence context. They both use the same database but the repository classes are in separate packages.
What do I need to do to setup the security pieces to use the 'entityManagerFactorySecurity' entity manager factory?

Thanks for you help in advance.

Miguel.

Using MySQL database for user authentication

Hi Stephan,

This project is really awesome. I'm learning a lot of Spring security from this. I have one question.

Connecting to MySQL database for user authentication. However, it returns Bad Credentials exception when I try to login.

In debug mode, I observed that at the time of logging in, it tries to extract username from the JWT token (the authentication request to the login endpoint will never contain a token, as a token will be generated by the server only after a user is authenticated in the login step).

My question:
When connecting to MySQL database for user authentication, does the doFilterInternal method in the JwtAuthenticationTokenFilter class need any change?
If yes, what are they?
If no, which other files need to be changed?

Rest service - User has been authenticated but no Mapping found for HTTP request

I am doing rest modules in Micro-services No JSP or Login page.
User is authenticated
[JwtAuthenticationTokenFilter.java:56]authenticated user admin, setting security context

PageNotFound [DispatcherServlet.java:1172]No mapping found for HTTP request with URI [/rest-moudle/test] in DispatcherServlet with name 'dispatcherServlet'

Below is my WebConfig. configure(HttpSecurity httpSecurity)
I pretty much opened every incoming request no matter what it is but still does not find the mapping page.
.antMatchers(HttpMethod.GET, "/").permitAll().antMatchers(HttpMethod.POST, "/").permitAll()
.antMatchers(HttpMethod.GET, "/").permitAll().antMatchers(HttpMethod.POST, "/").permitAll()
.antMatchers(HttpMethod.GET, "/").permitAll().antMatchers(HttpMethod.POST, "/").permitAll()

Send a custom error message if token expired

How to send a custom status code (or message) when the token has expired.

Tried subclassing the AuthenticationException subclass and threw exception in validateToken method. However it doesnt reach the commence method of the entry point class and the method instead throws 500 error.

Security - Implementation

Thanks for putting this online, I did try to implement this in my project, Sending JWT tokens as my Header.
for some reason, I am getting 403 forbidden error. I am not sure, what I am doing wrong or if I am missing any configuration. I have put the project on git hub, If someone can point me what the issue is.
https://github.com/vivdso/SpringAuthentication

Please assist.

Add expire and refresh feature for tokens

There should be a possibility to give a tokens a specific validity duration so that tokens expire after a certain interval. Furthermore there should be a possibility in the JS client to refresh the token. Maybe there is a kind of countdown in the UI, so that a user can see if a token expires.

  • Check expiration in org.zerhusen.security.JwtAuthenticationTokenFilter#doFilterInternal
  • Token refresh under org.zerhusen.security.controller.AuthenticationRestController#refreshAndGetAuthenticationToken

Always load from DB

Hello. I am interested in your project.
You comment "It is not compelling necessary to load the use details from the database." in JwtAuthenticationTokenFilter class.
I look at the JwtUserDetailsServiceImpl class with debug mode. when view web page, always access loadUserByUsername method. So still connect database.

Error BadCredentialsException

Hello,
when I try to login from the example page gives me the following error:

org.springframework.security.authentication.BadCredentialsException .
control 2

And I created the database, but not how it can be corrected

regards

Use OncePerRequestFilter as base class instead of GenericFilterBean

Thanks for this great example!

I don't think it's worth opening a pull request over this, but I would recommend anyone using this pattern in production to extend OncePerRequestFilter on the JwtAuthenticationTokenFilter as opposed to GenericFilterBean as it stops the chain from calling the filter multiple times per request, which is critical when doing things asynchronously :-)

public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {}

Encoded password does not look like BCrypt

I generated hash password in https://bcrypt-generator.com/
Client: Postman

DB password: :$ 2y$10$cZWIQLCT.AUu6/f.54ri/uX5VeMAANDY1f3wLh8NpVi6.mljPh7DO

enc : $2y$10$cZWIQLCT.AUu6/f.54ri/uX5VeMAANDY1f3wLh8NpVi6.mljPh7DO
raw : $2y$10$cZWIQLCT.AUu6/f.54ri/uX5VeMAANDY1f3wLh8NpVi6.mljPh7DO
Password param : $2y$10$cZWIQLCT.AUu6/f.54ri/uX5VeMAANDY1f3wLh8NpVi6.mljPh7DO

Encoded password does not look like BCrypt
I debugged it and it failed in if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
Both password is the same I double checked them in debug mode

spring.BCryptPasswordEncoder.java
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (encodedPassword == null || encodedPassword.length() == 0) {
logger.warn("Empty encoded password");
return false;
}

	// fialed here : encodedPassword is not match with BCRYPT_PATTERN

	if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
		logger.warn("Encoded password does not look like BCrypt");
		return false;
	}

	return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
}

I just hash a raw password with EncodedPassword from Spring but the same issue was faced.
Any suggestion ?

Getting users from database

I am trying to get users from a database.
I have added the following code to the application.yml file,
hibernate:
# possible values: validate | update | create | create-drop
ddl-auto: create-drop
datasource:
url: jdbc:mysql://localhost:3306/user_management
username: root
password:
driver-class-name: com.mysql.jdbc.Driver`

I have a database with one user, but when I enter the credentials in postman I get the following exception "java.lang.StackOverflowError".
How should I modify the code to make it work?

Repeated dependency

Hello:

I noticed there is a repeated dependency:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

Kind regards

User credentials validation

Thanks for sharing this wonderful project. One thing I don't understand how is it validating the user password(I understand the userName validation part and retrieving user from db using userName)? I have gone through the whole project and even executed the same successfully, If i provide an Incorrect password it is showing BadCredentialsException in UI. would you please explain how is it happening because it is no where written to verify the password.

Use Basic Authentication

Hi Stephan, and thank you for the effort in this project.
How and what do I need to do to use Basic Authentication instead of the raw JSON username and password to request a token? I am unable to find any spring boot project/example that uses both Basic authentication and JWT to maximize security.
Thank you

Parse DATETIME error

Hello, Stephan:

First of all, thanks for sharing this project, it's great.
I simply noticed when running the application that there was a minor bug when trying to insert the users:

2016-05-20 10:52:51.939 INFO 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export 2016-05-20 10:52:51.970 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000388: Unsuccessful: INSERT INTO USER (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE) VALUES (1, 'admin', '$2a$08$lDnHPz7eUkSi6ao14Twuau08mzhWrL4kyZGGU5xfiGALO/Vxd5DOi', 'admin', 'admin', 1, PARSEDATETIME('01-JAN-2016','dd-MMM-yyyy')) 2016-05-20 10:52:51.970 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : Error interpretando "01-JAN-2016" Error parsing "01-JAN-2016"; SQL statement: INSERT INTO USER (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE) VALUES (1, 'admin', '$2a$08$lDnHPz7eUkSi6ao14Twuau08mzhWrL4kyZGGU5xfiGALO/Vxd5DOi', 'admin', 'admin', 1, PARSEDATETIME('01-JAN-2016','dd-MMM-yyyy')) [90014-191] 2016-05-20 10:52:51.971 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000388: Unsuccessful: INSERT INTO USER (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE) VALUES (2, 'user', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 'user', 'user', 1, PARSEDATETIME('01-JAN-2016','dd-MMM-yyyy')) 2016-05-20 10:52:51.971 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : Error interpretando "01-JAN-2016" Error parsing "01-JAN-2016"; SQL statement: INSERT INTO USER (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE) VALUES (2, 'user', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 'user', 'user', 1, PARSEDATETIME('01-JAN-2016','dd-MMM-yyyy')) [90014-191] 2016-05-20 10:52:51.972 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000388: Unsuccessful: INSERT INTO USER (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE) VALUES (3, 'disabled', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 'user', 'user', 0, PARSEDATETIME('01-JAN-2016','dd-MMM-yyyy')) 2016-05-20 10:52:51.972 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : Error interpretando "01-JAN-2016" Error parsing "01-JAN-2016"; SQL statement: INSERT INTO USER (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE) VALUES (3, 'disabled', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 'user', 'user', 0, PARSEDATETIME('01-JAN-2016','dd-MMM-yyyy')) [90014-191] 2016-05-20 10:52:51.979 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000388: Unsuccessful: INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (1, 1) 2016-05-20 10:52:51.980 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : Violaciรณn de una restricciรณn de Integridad Referencial: "FK_5LOSSCGU02YAEJ7PRAP7O6G5S: PUBLIC.USER_AUTHORITY FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (1)" Referential integrity constraint violation: "FK_5LOSSCGU02YAEJ7PRAP7O6G5S: PUBLIC.USER_AUTHORITY FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (1)"; SQL statement: INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (1, 1) [23506-191] 2016-05-20 10:52:51.985 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000388: Unsuccessful: INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (1, 2) 2016-05-20 10:52:51.985 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : Violaciรณn de una restricciรณn de Integridad Referencial: "FK_5LOSSCGU02YAEJ7PRAP7O6G5S: PUBLIC.USER_AUTHORITY FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (1)" Referential integrity constraint violation: "FK_5LOSSCGU02YAEJ7PRAP7O6G5S: PUBLIC.USER_AUTHORITY FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (1)"; SQL statement: INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (1, 2) [23506-191] 2016-05-20 10:52:51.986 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000388: Unsuccessful: INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (2, 1) 2016-05-20 10:52:51.986 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : Violaciรณn de una restricciรณn de Integridad Referencial: "FK_5LOSSCGU02YAEJ7PRAP7O6G5S: PUBLIC.USER_AUTHORITY FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (2)" Referential integrity constraint violation: "FK_5LOSSCGU02YAEJ7PRAP7O6G5S: PUBLIC.USER_AUTHORITY FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (2)"; SQL statement: INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (2, 1) [23506-191] 2016-05-20 10:52:51.987 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000388: Unsuccessful: INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (3, 1) 2016-05-20 10:52:51.987 ERROR 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : Violaciรณn de una restricciรณn de Integridad Referencial: "FK_5LOSSCGU02YAEJ7PRAP7O6G5S: PUBLIC.USER_AUTHORITY FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (3)" Referential integrity constraint violation: "FK_5LOSSCGU02YAEJ7PRAP7O6G5S: PUBLIC.USER_AUTHORITY FOREIGN KEY(USER_ID) REFERENCES PUBLIC.USER(ID) (3)"; SQL statement: INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (3, 1) [23506-191] 2016-05-20 10:52:51.987 INFO 42707 --- [ost-startStop-1] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete

I simply modified the first 3 SQL statements in the file 'import.sql' to use a valid DATE format:

INSERT INTO USER (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE) VALUES (1, 'admin', '$2a$08$lDnHPz7eUkSi6ao14Twuau08mzhWrL4kyZGGU5xfiGALO/Vxd5DOi', 'admin', 'admin', 1, PARSEDATETIME('01-01-2016','dd-MM-yyyy')); INSERT INTO USER (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE) VALUES (2, 'user', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 'user', 'user', 1, PARSEDATETIME('01-01-2016','dd-MM-yyyy')); INSERT INTO USER (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE) VALUES (3, 'disabled', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 'user', 'user', 0, PARSEDATETIME('01-01-2016','dd-MM-yyyy'));

...and it worked fine, so then I was able to check the authorization for the three users.

Thanks again and good job!

java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.module.SimpleModule

Hi,

Having run your code, I got the below error.

java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/module/SimpleModule
	at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_101]
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_101]
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_101]
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[na:1.8.0_101]
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[na:1.8.0_101]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[na:1.8.0_101]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[na:1.8.0_101]
	at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_101]
	at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[na:1.8.0_101]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_101]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_101]
	at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_101]
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_101]
	at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_101]
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:613) ~[spring-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:524) ~[spring-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:510) ~[spring-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:570) ~[spring-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:696) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:639) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:608) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1476) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:425) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:395) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96) ~[spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:686) ~[spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:524) ~[spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.zerhusen.JwtDemoApplication.main(JwtDemoApplication.java:10) [classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
	at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:507) [spring-boot-maven-plugin-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101]
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.module.SimpleModule
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_101]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_101]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_101]
	... 40 common frames omitted

2017-06-13 09:25:11.315  INFO 6026 --- [           main] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@77813013: startup date [Tue Jun 13 09:25:10 IST 2017]; root of context hierarchy
2017-06-13 09:25:11.317  WARN 6026 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception thrown from LifecycleProcessor on context close

java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@77813013: startup date [Tue Jun 13 09:25:10 IST 2017]; root of context hierarchy
	at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:417) [spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1002) [spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:961) [spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:818) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.zerhusen.JwtDemoApplication.main(JwtDemoApplication.java:10) [classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
	at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:507) [spring-boot-maven-plugin-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101]

2017-06-13 09:25:11.318 ERROR 6026 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Destroy method on bean with name 'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory' threw an exception

java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@77813013: startup date [Tue Jun 13 09:25:10 IST 2017]; root of context hierarchy
	at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:404) [spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.context.support.ApplicationListenerDetector.postProcessBeforeDestruction(ApplicationListenerDetector.java:97) ~[spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:253) ~[spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578) [spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554) [spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:959) [spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523) [spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:966) [spring-beans-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1033) [spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1009) [spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:961) [spring-context-4.3.5.RELEASE.jar:4.3.5.RELEASE]
	at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:818) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at org.zerhusen.JwtDemoApplication.main(JwtDemoApplication.java:10) [classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
	at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:507) [spring-boot-maven-plugin-1.4.3.RELEASE.jar:1.4.3.RELEASE]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101]

[WARNING] 
java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:507)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/module/SimpleModule
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
	at java.lang.Class.getDeclaredMethods(Class.java:1975)
	at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:613)
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:524)
	at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:510)
	at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:570)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:696)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:639)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:608)
	at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1476)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:425)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:395)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:513)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:506)
	at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1189)
	at org.springframework.boot.SpringApplication.getExitCodeFromMappedException(SpringApplication.java:886)
	at org.springframework.boot.SpringApplication.getExitCodeFromException(SpringApplication.java:872)
	at org.springframework.boot.SpringApplication.handleExitCode(SpringApplication.java:858)
	at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:812)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:326)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175)
	at org.zerhusen.JwtDemoApplication.main(JwtDemoApplication.java:10)
	... 6 more
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.module.SimpleModule
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 41 more
[INFO] ------------------------------------------------------------------------

The root cause seems to be because of missing class `com.fasterxml.jackson.databind.module.SimpleModule` in jackson-databind jar version 2.8.5. I got this dependency with `spring-boot 1.4.3.RELEASE`. To fix this dependency issue, I had to upgrade the springboot version to `1.5.3.RELEASE`.

I suspect many people would be facing this similar issue. Could you please upgrade to 1.5.3.RELEASE for smoother executions.

I would like to thank you very much for creating this demo. It really helped me in understanding and implementing jwt.

Thanks again,
Harshavardhan M

import.sql for postgres

This is my import,sqk for running the project using postgres

CREATE TABLE usuario
(
id integer NOT NULL,
username character varying(50) NOT NULL,
password character varying(100) NOT NULL,
firstname character varying(50) NOT NULL,
lastname character varying(50) NOT NULL,
enabled boolean,
lastpasswordresetdate timestamp without time zone NOT NULL,
CONSTRAINT user_pkey PRIMARY KEY (id)
);

CREATE TABLE authority
(
id integer NOT NULL,
name character varying(50) NOT NULL,
CONSTRAINT authority_pkey PRIMARY KEY (id)
);

CREATE TABLE user_authority
(
user_id integer NOT NULL,
authority_id integer NOT NULL,
CONSTRAINT fk_authority_id_user_authority FOREIGN KEY (authority_id)
REFERENCES authority (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_usuario_user_authority FOREIGN KEY (user_id)
REFERENCES usuario (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
);

INSERT INTO usuario (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE)
VALUES (1, 'admin', '$2a$08$lDnHPz7eUkSi6ao14Twuau08mzhWrL4kyZGGU5xfiGALO/Vxd5DOi', 'admin', 'admin', TRUE, to_date('01-06-2016','dd-MMM-yyyy'));
INSERT INTO usuario (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE)
VALUES (2, 'user', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 'user', 'user', TRUE, to_date('01-06-2016','dd-MMM-yyyy'));
INSERT INTO usuario (ID, USERNAME, PASSWORD, FIRSTNAME, LASTNAME, ENABLED, LASTPASSWORDRESETDATE)
VALUES (3, 'disabled', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 'user', 'user', FALSE, to_date('01-06-2016','dd-MMM-yyyy'));

INSERT INTO AUTHORITY (ID, NAME) VALUES (1, 'ROLE_USER');
INSERT INTO AUTHORITY (ID, NAME) VALUES (2, 'ROLE_ADMIN');

INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (1, 1);
INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (1, 2);
INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (2, 1);
INSERT INTO USER_AUTHORITY (USER_ID, AUTHORITY_ID) VALUES (3, 1);

AuthenticationManagerBean

Hey, great job with this project - sadly for me I can't get it to work. I'm trying to implement it on a project for my college that's making us transition from the good old cookies to tokens, and I tried to do it as you but I'm getting an error that the authenticationManager can't be autowired on the authenticationrestcontroller - do you know why it could be? Thanks in advanced

InternalAuthenticationServiceException

whenever I try to login it throws this exception (org.springframework.security.authentication.InternalAuthenticationServiceException), and I don't know why.

Extend JwtAuthenticationTokenFilter from GenericFilterBean instead of UsernamePasswordAuthenticationFilter

This enhancement based on the comment https://www.toptal.com/java/rest-security-with-jwt-spring-security-and-java#comment-2797220982.

Actually the JwtAuthenticationTokenFilter extends the UsernamePasswordAuthenticationFilter and the question was why it not extends the simple GenericFilterBean. I checked that and everything seems to work fine. Extending the GenericFilterBean makes the WebSecurityConfig a little bit easier.

Problem in MAC

I have 2 MacBooks Pro retina and your code does not work on them. However, in my Ubuntu SO it works perfect ! What could be the reason?

oauth2 ? :)

thanks man this is so helpful for me..i am waiting for more :) can i folk this ? thanks

Unnecessary check for username

Looks like jwtTokenUtil.validateToken() should check only dates and should omit checking username. Since we use private key during token generation step Client has no ability to change username inside token. That's will save us one DB call for each request.

User Roles at front end

Hi, Did not find on how to get corresponding user roles in front end.
Pls help to give some direction . I am able to get the token in my angular front end . So the authentication is fine. How about the roles to read ? If the token also has the role information then which api or helper can help to read the roles from token in the angular app.

Pls help .

refresh token

Hi, tnx for big work.
I have a question. When i have to use refresh token?

Please check below error while running application

   ___       ________   _____            _                ____
  / / |     / /_  __/  / ___/____  _____(_)___  ____ _   / __ \___  ____ ___  ____

__ / /| | /| / / / / __ / __ / / / __ / __ / / / / / _ \/ __ / __
/ /
/ / | |/ |/ / / / / / // / / / / / / / // / / // / / / / / / / // /
_
/ |/|/ // // .// /// //_, / /___/_// // //_/
/
/ /
__/
2017-03-22 12:38:56.376 INFO 8196 --- [ main] org.zerhusen.JwtDemoApplication : Starting JwtDemoApplication on LAPTOP-QOV191CS with PID 8196 (C:\git\security\jwt-spring-security-demo\target\classes started by vishnu in C:\git\security\jwt-spring-security-demo)
2017-03-22 12:38:56.392 INFO 8196 --- [ main] org.zerhusen.JwtDemoApplication : No active profile set, falling back to default profiles: default
2017-03-22 12:38:56.533 INFO 8196 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@671a5887: startup date [Wed Mar 22 12:38:56 IST 2017]; root of context hierarchy
2017-03-22 12:39:00.582 INFO 8196 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [class org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$64c41eaf] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-03-22 12:39:00.703 INFO 8196 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration' of type [class org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration$$EnhancerBySpringCGLIB$$fd71e6e9] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-03-22 12:39:00.735 INFO 8196 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'objectPostProcessor' of type [class org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-03-22 12:39:00.735 INFO 8196 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler@6c0905f6' of type [class org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-03-22 12:39:00.750 INFO 8196 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration' of type [class org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration$$EnhancerBySpringCGLIB$$2246899b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-03-22 12:39:00.782 INFO 8196 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'methodSecurityMetadataSource' of type [class org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-03-22 12:39:01.750 INFO 8196 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2017-03-22 12:39:01.759 INFO 8196 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2017-03-22 12:39:01.759 INFO 8196 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.6
2017-03-22 12:39:01.994 INFO 8196 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-03-22 12:39:01.994 INFO 8196 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 5461 ms
2017-03-22 12:39:03.218 ERROR 8196 --- [ost-startStop-1] o.s.b.c.embedded.tomcat.TomcatStarter : Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter': Unsatisfied dependency expressed through constructor parameter 3; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration$$EnhancerBySpringCGLIB$$f57c3d0f]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jacksonHttpMessageConverter' defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter]: Factory method 'jacksonHttpMessageConverter' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'config' defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.rest.core.config.RepositoryRestConfiguration]: Factory method 'config' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'repositories' defined in class path resource [org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.repository.support.Repositories]: Factory method 'repositories' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userRepository': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.Class<org.springframework.data.repository.Repository>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2017-03-22 12:39:03.274 WARN 8196 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
2017-03-22 12:39:03.431 ERROR 8196 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :


APPLICATION FAILED TO START


Description:

Parameter 0 of constructor in org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean required a bean of type 'java.lang.Class' that could not be found.

Action:

Consider defining a bean of type 'java.lang.Class' in your configuration.

Why is there a need to have UsernamePasswordAuthenticationFilter?

Hello, I've set up your project with some modifications to run without spring boot and noticed that having addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); causes the request flow to stop, specifically in these lines under UsernamePasswordAuthenticationFilter:

String username = obtainUsername(request);
		String password = obtainPassword(request);

		if (username == null) {
			username = "";
		}

		if (password == null) {
			password = "";
		}

		username = username.trim();

		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
				username, password);

		// Allow subclasses to set the "details" property
		setDetails(request, authRequest);

		return this.getAuthenticationManager().authenticate(authRequest);

since obtainUsername does nothing but call request.getParameter(usernameParameter); which returns an empty string my question is Why is there a need to have this filter if the JW token has already been validated?

org.hibernate.dialect.MySQL5Dialect does not support sequences

Hi and thanks for the code. This is not an issue, it is more a doubt. You suggested that it could be possible to add a MySQL database. However, it doest not support sequences. So, what could it be done in order to not get problems with the algorithm but change the GenerationType.SEQUENCE in the class Authority:
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "authority_seq")

error: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory: org.hibernate.dialect.MySQL5Dialect does not support sequences

Thanks again.

How can I refresh after the token time expires?

Hi, Thank you for your opensource.
I am practicing with your source. However, it did not refresh after the token time expired.
I hope that the token is refreshed without sign in again. Please let me know what you need to refer to.

Getting authentication errors with new pages

Hi Stephan!

I'm probably doing something wrong but I had no way to contact you other than creating an issue because I couldn't find your email address. You may contact me at psotos at epicproportionstour dot com. I see you are also in the music business which is super cool!

In any case, I have created a new RestController and mirrored the code from the MethodProtectedRestController, and my new Restful endpoint gets a 401 status whether i am logged in or not. Here is the new code:

package com.eptent.repository;

import com.eptent.model.Campaign;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.security.access.prepost.PreAuthorize;


/**
 * @author psotos
 *
 */
@RepositoryRestResource(collectionResourceRel = "campaign", path = "campaign")
@PreAuthorize("hasRole('GM')")
public interface CampaignRepository extends MongoRepository<Campaign, String> {
	Campaign findById(String id);
	Campaign findByName(String name);
	

}

I also tried this and get the same problem:

package com.eptent.routes;


import java.util.concurrent.atomic.AtomicLong;

import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;



@RestController
public class HelloTestController {
	


	    private static final String template = "Hello, %s!";
	    private final AtomicLong counter = new AtomicLong();

	    @RequestMapping(value="hellotest", method=RequestMethod.GET)
	    @PreAuthorize("hasRole('ADMIN')")
	    public ResponseEntity<?> hellotest(@RequestParam(value="name", defaultValue="World") String name) {
	    	
	        
	        return ResponseEntity.ok(new HelloTest(counter.incrementAndGet(),
	                            String.format(template, name)).getContent());
	    }
	}

Any help is greatly appreciated!

Create UserDetails from JWT claims

If I understand the code correctly in JwtAuthenticationTokenFilter, on every request for data from the api, a database call is made to build the UserDetails, based on username. Would it not be better create the UserDetails based on the claims as parsed from the JWT?

Cheers,

Jim

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.