{"id":45203,"date":"2017-01-24T19:01:07","date_gmt":"2017-01-24T13:31:07","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=45203"},"modified":"2022-01-10T18:40:41","modified_gmt":"2022-01-10T13:10:41","slug":"fortifying-your-rest-api-using-spring-security","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/fortifying-your-rest-api-using-spring-security\/","title":{"rendered":"Fortifying your REST API using Spring security"},"content":{"rendered":"<p><a title=\"Spring security\" href=\"https:\/\/projects.spring.io\/spring-security\/\"><b>Spring Security<\/b><\/a><span style=\"font-weight: 400\"> is a lightweight security framework that provides authentication and authorization support in order to secure <a href=\"https:\/\/spring.io\/\">Spring-based<\/a> applications. It comes bundled with popular security algorithm implementations.<\/span><\/p>\n<p>I would cover a series of different topic related to <a href=\"https:\/\/projects.spring.io\/spring-security\/\">spring security<\/a>\u00a0in my upcoming blogs. We will go through the setup process first, then analyze when and where to apply, explore different authentication methods and securing password with encoding schemes.<\/p>\n<p><b>User and Role Management<\/b><span style=\"font-weight: 400\">\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400\">Suppose you want\u00a0to create a REST application,\u00a0<\/span><b>User and Role management system to\u00a0<\/b><span style=\"font-weight: 400\">give each user a set of roles that grants access to the different functions. Also give users privileges as per the role and capability to apply the\u00a0role to specific assets, networks, or other objects.<\/span><\/p>\n<p>In this scenario, you can view the existing users, their roles and privileges from the Administration section. And only\u00a0the user of Administration privilege would be allowed\u00a0to create\/update other users.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/01\/15.jpg\" alt=\"\" width=\"860\" height=\"360\" class=\"aligncenter size-full wp-image-54487\" \/><\/p>\n<p><span style=\"font-weight: 400\">If you are a <\/span><span style=\"font-weight: 400\">Spring user and new to <a title=\"Spring security\" href=\"https:\/\/projects.spring.io\/spring-security\/\">Spring security<\/a>, basic authentication would be best option to start with and for demonstration, we\u2019ll be creating a sample application using the following tech stack:<\/span><\/p>\n<table style=\"height: 187px\" width=\"624\">\n<tbody>\n<tr>\n<td><span style=\"color: #000080\">Build Tool \u00a0\u00a0<\/span><\/td>\n<td><a href=\"https:\/\/gradle.org\/\"><span style=\"font-weight: 400\">Gradle 2.3 or higher<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"color: #000080\">Web framework<\/span><\/td>\n<td><a href=\"https:\/\/projects.spring.io\/spring-boot\/\"><span style=\"font-weight: 400\">Spring Boot 1.4.3.RELEASE<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"color: #000080\">Security Tool<\/span><\/td>\n<td><a title=\"Spring security\" href=\"https:\/\/projects.spring.io\/spring-security\/\"><span style=\"font-weight: 400\">Spring security<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"color: #000080\">Repository<\/span><\/td>\n<td><a href=\"https:\/\/www.mysql.com\/\"><span style=\"font-weight: 400\">MySQL<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"color: #000080\">ORM Tool<\/span><\/td>\n<td><a href=\"http:\/\/projects.spring.io\/spring-data\/\"><span style=\"font-weight: 400\">Spring Data Jpa<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td><span style=\"color: #000080\">Version Control<\/span><\/td>\n<td><a href=\"https:\/\/en.wikipedia.org\/wiki\/Git\"><span style=\"font-weight: 400\">GIT<\/span><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For simplicity there will be 3 types of users in this application:<\/p>\n<table style=\"height: 121px\" width=\"624\">\n<tbody>\n<tr>\n<td><b>Role<\/b><\/td>\n<td><b>Permission<\/b><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;color: #000080\">ADMIN<\/span><\/td>\n<td><span style=\"font-weight: 400\">Create user, View users<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;color: #000080\">USER<\/span><\/td>\n<td><span style=\"font-weight: 400\">Can view\/update own details<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;color: #000080\">ANONYMOUS<\/span><\/td>\n<td><span style=\"font-weight: 400\">Can only view total no of users in the system<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><b>Step 1: Application Setup<\/b><\/p>\n<p>Let\u2019s start with a very basic application (in terms of setup needed) that boots a Spring application context. Two tools that will help us with that are\u00a0<a title=\"Gradle\" href=\"https:\/\/gradle.org\/\">Gradle<\/a> and <a title=\"Spring Boot\" href=\"https:\/\/projects.spring.io\/spring-boot\/\">Spring Boot<\/a>.<\/p>\n<p><span style=\"font-weight: 400\">I skip lines that aren\u2019t particularly interesting like the maven repository configuration. You can find the complete code at <\/span><a href=\"https:\/\/github.com\/bjpaul\/restful-spring-security\/blob\/basic-crud\/build.gradle\"><span style=\"font-weight: 400\">GitHub<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<\/p>\n<p>apply plugin: &#8216;org.springframework.boot&#8217;<\/p>\n<p>dependencies {<br \/>\n\tcompile(&#8216;org.springframework.boot:spring-boot-starter-data-jpa&#8217;)<br \/>\n\tcompile(&#8216;org.springframework.boot:spring-boot-starter-web&#8217;)<br \/>\n\truntime(&#8216;mysql:mysql-connector-java:5.1.13&#8217;)<br \/>\n}<\/p>\n<p>[\/sourcecode]<\/p>\n<p><span style=\"font-weight: 400\">Here we are using<\/span><span style=\"font-weight: 400\"><span style=\"color: #339966\">: spring-boot-starter-data-jpa<\/span>\u00a0as the<\/span><span style=\"font-weight: 400\">\u00a0ORM tool.<\/span><\/p>\n<p><b>Step 2 : CRUD for User entity<\/b><\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<br \/>\n@Entity<br \/>\npublic class UserDetail {<br \/>\n    @Id<br \/>\n    @GeneratedValue(strategy = GenerationType.AUTO)<br \/>\n    private long id;<\/p>\n<p>    private String name;<\/p>\n<p>\tprivate int age;<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p>Create the following api\u2019s for <strong><span class=\"kix-wordhtmlgenerator-word-node\" style=\"font-size: 14.6667px;font-family: 'Courier New';color: #bf616a;background-color: #f4f4f4;font-style: normal;text-decoration: none;vertical-align: baseline\">UserDetail<\/span><\/strong> Entity:<\/p>\n<table style=\"height: 259px\" width=\"901\">\n<tbody>\n<tr>\n<td><b>URL<\/b><\/td>\n<td><b>Method<\/b><\/td>\n<td><b>Description<\/b><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;color: #000080\">{host}\/user\/<\/span><\/td>\n<td><span style=\"font-weight: 400\">GET<\/span><\/td>\n<td><span style=\"font-weight: 400\">List all user details<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;color: #000080\">{host}\/user\/{id}<\/span><\/td>\n<td><span style=\"font-weight: 400\">GET<\/span><\/td>\n<td><span style=\"font-weight: 400\">Fetch specific user detail<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;color: #000080\">{host}\/user\/<\/span><\/td>\n<td><span style=\"font-weight: 400\">POST<\/span><\/td>\n<td><span style=\"font-weight: 400\">Add new user<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;color: #000080\">{host}\/user\/{id}<\/span><\/td>\n<td><span style=\"font-weight: 400\">PUT<\/span><\/td>\n<td><span style=\"font-weight: 400\">Update detail for a user<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;color: #000080\">{host}\/user\/{id}<\/span><\/td>\n<td><span style=\"font-weight: 400\">DELETE<\/span><\/td>\n<td><span style=\"font-weight: 400\">Delete a specific user<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-weight: 400;color: #000080\">{host}\/user\/<\/span><\/td>\n<td><span style=\"font-weight: 400\">DELETE<\/span><\/td>\n<td><span style=\"font-weight: 400\">Delete all user<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-weight: 400\">You can find the complete code for CRUD and Api\u2019s at <\/span><a href=\"https:\/\/github.com\/bjpaul\/restful-spring-security\/blob\/basic-crud\/src\/main\/java\/org\/basic\/spring\/security\/rest\/controller\/UserController.java\"><span style=\"font-weight: 400\">GitHub<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n<p><b>Step 3: User Authentication<\/b><\/p>\n<p>Now we need an authentication mechanism to allow only authenticated users\u00a0to access the system.<\/p>\n<p>Add a domain for user credentials:<\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<br \/>\n@Entity<br \/>\npublic class Authentication {<\/p>\n<p>\t@Id<br \/>\n\tprivate String username;<br \/>\n\tprivate String password;<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p><span style=\"font-weight: 400\">Associate it with the <strong><span class=\"kix-wordhtmlgenerator-word-node\" style=\"font-size: 14.6667px;font-family: 'Courier New';color: #bf616a;background-color: #f4f4f4;font-style: normal;text-decoration: none;vertical-align: baseline\">UserDetail<\/span><\/strong> domain:<\/span><\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<br \/>\n@Entity<br \/>\npublic class UserDetail {<br \/>\n    &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<\/p>\n<p>\t@OneToOne(cascade= CascadeType.ALL)<br \/>\n\t@JoinColumn(name = &#8216;user_authentication_id&#8217;)<br \/>\n\tprivate Authentication authentication;<\/p>\n<p>\t&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p><span style=\"font-weight: 400\">Add spring security dependency in <\/span><strong><span class=\"kix-wordhtmlgenerator-word-node\" style=\"font-size: 14.6667px;font-family: 'Courier New';color: #bf616a;background-color: #f4f4f4;font-style: normal;text-decoration: none;vertical-align: baseline\">build.gradle<\/span><\/strong><\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<\/p>\n<p>dependencies {<br \/>\n &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<\/p>\n<p> compile(&#8216;org.springframework.boot:spring-boot-starter-security&#8217;)<\/p>\n<p> &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<br \/>\n}<\/p>\n<p>[\/sourcecode]<\/p>\n<p>And\u00a0configure your application to enable basic authentication using below code: \u00a0<strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">org.springframework.security.core.userdetails.UserDetailsService<\/span><\/strong><\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<br \/>\n@EnableWebSecurity<br \/>\npublic class ApiSecurityConfig extends WebSecurityConfigurerAdapter{<\/p>\n<p> &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<br \/>\n &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.<\/p>\n<p> @Autowired<br \/>\n public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {<br \/>\n     auth.userDetailsService(userDetailsService);<br \/>\n }<\/p>\n<p> @Override<br \/>\n protected void configure(HttpSecurity http) throws Exception {<\/p>\n<p>     http<br \/>\n      .authorizeRequests()<br \/>\n      .anyRequest().authenticated()<br \/>\n      .and()<br \/>\n      .httpBasic().authenticationEntryPoint(entryPoint)<br \/>\n      .and()<br \/>\n      .exceptionHandling().accessDeniedHandler(handler);<br \/>\n  }<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p>Here we are configuring Spring security by overriding individual methods of\u00a0<strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter<\/span><\/strong>. <strong><span style=\"font-weight: 400\">\u00a0<strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">@EnableWebSecurity<\/span><\/strong>\u00a0 that helps to auto-configure this.<\/span><\/strong><\/p>\n<p>To enable Spring Security integration with Spring MVC add the <strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">@EnableWebSecurity<\/span><\/strong><\/span><\/strong><\/strong>\u00a0annotation to your configuration.<\/p>\n<p><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">configureGlobalSecurity<\/span><\/strong><\/span><\/strong><\/strong>\u00a0<span style=\"font-weight: 400\">method is pretty straightforward, we are just providing the implementation for <\/span><span style=\"font-weight: 400\">UserDetailService <\/span><span style=\"font-weight: 400\">as<\/span><span style=\"font-weight: 400\">\u00a0the <span style=\"color: #000000\">\u00a0<strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\">AuthenticationProvider\u00a0<\/span><\/strong><\/span><\/strong><\/strong><\/span><\/span><\/p>\n<p><span style=\"font-weight: 400\">In <\/span><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">configure\u00a0<\/span><\/strong><\/span><\/strong><\/strong><span style=\"font-weight: 400\">method we are using \u00a0<span style=\"color: #000000\"><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\">HTTP Basic Authentication<\/span><\/strong><\/span><\/strong><\/strong><\/span>, \u00a0also providing the \u00a0Implementation of <strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">AuthenticationEntryPoint\u00a0<\/span><\/strong><\/span><\/strong><\/strong>and\u00a0<strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">AccessDeniedHandler\u00a0<\/span><\/strong><\/span><\/strong><\/strong>\u00a0for \u00a0handling\u00a0<span style=\"color: #000000\"><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\">Authentication<\/span><\/strong><\/span><\/strong><\/strong><\/span>\u00a0 exception and\u00a0<span style=\"color: #000000\"><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\">Access denied<\/span><\/strong><\/span><\/strong><\/strong><\/span>\u00a0exception.<\/span><\/p>\n<p><span style=\"font-weight: 400\">The implementation for\u00a0<strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">UserDetailService<\/span><\/strong><\/span><\/strong><\/strong>\u00a0is pretty straightforward and self-descriptive,\u00a0<\/span><a href=\"https:\/\/github.com\/bjpaul\/restful-spring-security\/blob\/user-authentication\/src\/main\/java\/org\/basic\/spring\/security\/rest\/service\/AuthenticationService.java\"><span style=\"font-weight: 400\">GitHub<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n<p>Let\u2019s test the functionality using <a href=\"https:\/\/chrome.google.com\/webstore\/detail\/postman\/fhbjgbiflinjbdggehcddcbncdddomop?hl=en\">postman<\/a>\u00a0. Or you can pick any other REST client.<\/p>\n<p>\u21d2 On accessing <span style=\"color: #000080\"><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\">GET : &lt;host&gt;\/user\/\u00a0<\/span><\/strong><\/span><\/strong><\/strong><\/span>we\u2019ll get an\u00a0authentication error as below:<\/p>\n<p><span style=\"font-weight: 400\"><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">HTTP Status 401 : <span style=\"color: #000000\">Full authentication is required to access this resource<\/span><\/span><\/strong><\/span><\/strong><\/strong><\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-45654\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/01\/auth-error-get.gif\" alt=\"auth-error-get\" width=\"1200\" height=\"800\" \/><\/p>\n<p>To resolve this we are adding a new user with sample credential\u00a0using the following script:<\/p>\n<p>[sourcecode language=&#8221;sql&#8221;]<br \/>\ninsert into authentication(username, password) values(&#8216;username1&#8217;, &#8216;password1&#8217;);<br \/>\ninsert into user_detail(age, name,user_authentication_id) values(23, &#8216;User 1&#8242;,&#8217;username1&#8217;);<br \/>\n[\/sourcecode]<\/p>\n<p>Now add the same credential in postman with basic authentication<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-45657\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/01\/auth-success.gif\" alt=\"auth-success\" width=\"1200\" height=\"800\" \/><\/p>\n<p>In response, a token is automatically added into the header with key <strong>\u00a0<strong><strong><strong>Authorization<\/strong><\/strong><\/strong><\/strong><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-45213\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/01\/10.png\" alt=\"10\" width=\"1664\" height=\"338\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2017\/01\/10.png 1664w, \/blog\/wp-ttn-blog\/uploads\/2017\/01\/10-300x60.png 300w, \/blog\/wp-ttn-blog\/uploads\/2017\/01\/10-1024x208.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2017\/01\/10-624x126.png 624w\" sizes=\"(max-width: 1664px) 100vw, 1664px\" \/><strong><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\">Basic dXNlcm5hbWUxOnBhc3N3b3JkMQ==\u00a0<\/span><\/strong><\/span><\/strong><\/strong><\/strong><span style=\"font-weight: 400\">is the encoded form of <\/span><span style=\"font-weight: 400;color: #0000ff\">username1:password1<\/span><span style=\"font-weight: 400\">\u00a0in <\/span><span style=\"font-weight: 400\"><strong><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\">base64\u00a0<\/span><\/strong><\/span><\/strong><\/strong><\/strong><\/span><span style=\"font-weight: 400\">and prepended with <\/span><span style=\"font-weight: 400\"><span style=\"color: #0000ff\">\u2018Basic \u00a0\u2018<\/span>. <\/span><span style=\"font-weight: 400\">Now you can access all the API&#8217;s using this entry into the header.<\/span><\/p>\n<p>Again\u00a0we\u2019ll get forbidden error in <strong><strong><strong><strong>POST<\/strong><\/strong><\/strong><\/strong>\u00a0<strong><strong><strong><strong>PUT<\/strong><\/strong><\/strong><\/strong>\u00a0<strong><strong><strong><strong>DELETE<\/strong><\/strong><\/strong><\/strong> operation<\/p>\n<p><span style=\"font-weight: 400\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-45656\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/01\/csrf-error.gif\" alt=\"csrf-error\" width=\"1200\" height=\"800\" \/>To resolve this we can simply disable the CSRF configuration in\u00a0<strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">configure<\/span><\/strong><\/span><\/strong><\/strong>\u00a0method.<\/span><\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<br \/>\n@Override<br \/>\nprotected void configure(HttpSecurity http) throws Exception {<\/p>\n<p>  http.csrf().disable()<br \/>\n      .authorizeRequests()<br \/>\n      .anyRequest().authenticated()<br \/>\n      .and()<br \/>\n      .httpBasic().authenticationEntryPoint(entryPoint)<br \/>\n      .and()<br \/>\n      .exceptionHandling().accessDeniedHandler(handler);<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p><strong>When should we use CSRF protection?<\/strong><\/p>\n<p><strong>CSRF<\/strong> protection is a request that could be processed by a browser by normal users.<br \/>\nIf you are only creating a service that is used by non-browser clients, you will likely want to disable <strong>CSRF<\/strong> protection.<\/p>\n<p>To know more about CSRF, read <a href=\"https:\/\/www.owasp.org\/index.php\/Cross-Site_Request_Forgery_(CSRF)\">https:\/\/www.owasp.org\/index.php\/Cross-Site_Request_Forgery_(CSRF)<\/a><\/p>\n<p>As we discussed earlier<strong>\u00a0<strong><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\">ANONYMOUS<\/span><\/strong><\/span><\/strong><\/strong><\/strong><\/strong><span style=\"font-weight: 400\">\u00a0user can only view the total no of users in the system i.e API with URL\u00a0<\/span><span style=\"font-weight: 400\"><span style=\"color: #000080\"><strong><strong><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\"><strong>&lt;<\/strong><strong>host&gt;\/user\/count<\/strong><\/span><\/strong><\/span><\/strong><\/strong><\/strong><\/strong><\/span>. To do that change the <\/span><span style=\"font-weight: 400\">\u00a0<strong><strong><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\">chainRequestMatchers<\/span><\/strong><\/span><\/strong><\/strong><\/strong><\/strong><\/span><span style=\"font-weight: 400\">\u00a0in the\u00a0<strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">configure<\/span><\/strong><\/span><\/strong><\/strong><\/span><span style=\"font-weight: 400\">\u00a0method:<\/span><\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<br \/>\n@Override<br \/>\nprotected void configure(HttpSecurity http) throws Exception {<br \/>\n http.csrf().disable()<br \/>\n  .authorizeRequests()<br \/>\n  .antMatchers(&#8216;\/user\/count&#8217;).permitAll() \/\/ request matcher for anonymous user<br \/>\n  .antMatchers(&#8216;\/user\/**&#8217;).authenticated() \/\/ request matcher for authenticate user<br \/>\n  .and()<br \/>\n  .httpBasic().authenticationEntryPoint(entryPoint)<br \/>\n  .and()<br \/>\n  .exceptionHandling().accessDeniedHandler(handler);<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-45661\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/01\/anonymous.gif\" alt=\"anonymous\" width=\"1200\" height=\"800\" \/><\/p>\n<p><span style=\"font-weight: 400\">Find the complete code at <\/span><a href=\"https:\/\/github.com\/bjpaul\/restful-spring-security\/blob\/user-authentication\/src\/main\/java\/org\/basic\/spring\/security\/rest\/config\/ApiSecurityConfig.java\"><span style=\"font-weight: 400\">GitHub<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n<p><b>Step 4: User Authorization<\/b><\/p>\n<p><span style=\"font-weight: 400\">Now as per the use case non-administrator user will have access to the profile only. i.e<\/span>\u00a0<strong>\u00a0<strong><strong><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;font-family: 'Courier New';font-size: 14.6667px\"><span style=\"color: #000080\"><strong>GET: &lt;host&gt;\/user\/profile<\/strong><\/span>\u00a0<\/span><\/strong><\/span><\/strong><\/strong><\/strong><\/strong><\/strong>\u00a0.<\/p>\n<p>To manage this we need to introduce\u00a0<span style=\"color: #0000ff\">Role\/Authority<\/span> based authentication system.<\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<br \/>\n@Entity<br \/>\npublic class Role {<\/p>\n<p> @Id<br \/>\n @GeneratedValue(strategy = GenerationType.AUTO)<br \/>\n private Long id;<\/p>\n<p> @Column(unique = true)<br \/>\n private String authority;<\/p>\n<p> @ManyToMany(mappedBy = &#8216;roles&#8217;, fetch = FetchType.LAZY)<br \/>\n private Set&lt;Authentication&gt; users;<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p><span style=\"font-weight: 400\">And associate it with\u00a0<\/span><strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">Authentication\u00a0<\/span><\/strong><\/span><\/strong><\/strong>entity:<\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<br \/>\n@Entity<br \/>\npublic class Authentication {<\/p>\n<p> @Id<br \/>\n private String username;<br \/>\n private String password;<br \/>\n @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)<br \/>\n @JoinTable(<br \/>\n joinColumns = @JoinColumn(name = &#8216;user_id&#8217;), inverseJoinColumns = @JoinColumn(name = &#8216;role_id&#8217;)<br \/>\n )<br \/>\n private Set&lt;Role&gt; roles;<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p><span style=\"font-weight: 400\">Add user credentials and their roles\u00a0using the following script:<\/span><\/p>\n<p>[sourcecode language=&#8221;sql&#8221;]<br \/>\ninsert into role(authority) values(&#8216;ROLE_ADMIN&#8217;), (&#8216;ROLE_USER&#8217;);<br \/>\ninsert into authentication(username, password) values(&#8216;admin&#8217;, &#8216;password&#8217;),(&#8216;user&#8217;, &#8216;password&#8217;);<br \/>\ninsert into user_detail(age, name, user_authentication_id) values(25, &#8216;Admin user&#8217;,&#8217;admin&#8217;),(23, &#8216;user&#8217;,&#8217;user&#8217;);<br \/>\ninsert into authentication_roles values(&#8216;admin&#8217;,1),(&#8216;admin&#8217;,2),(&#8216;user&#8217;,2);<br \/>\n[\/sourcecode]<\/p>\n<p><span style=\"font-weight: 400\">Finally, modify the\u00a0<strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">UserDetailService<\/span><\/strong><\/span><\/strong><\/strong><\/span><span style=\"font-weight: 400\">\u00a0implementation by providing user authorities and\u00a0<strong><strong><span style=\"font-weight: 400\"><strong><span style=\"background-color: #f4f4f4;color: #bf616a;font-family: 'Courier New';font-size: 14.6667px\">configure<\/span><\/strong><\/span><\/strong><\/strong>\u00a0method to get the desired result.<\/span><\/p>\n<p>[sourcecode language=&#8221;java&#8221;]<br \/>\n@Override<br \/>\nprotected void configure(HttpSecurity http) throws Exception {<br \/>\n  http.csrf().disable()<br \/>\n   .authorizeRequests()<br \/>\n   .antMatchers(&#8216;\/user\/count&#8217;).permitAll()  \/\/ request matcher for anonymous user<br \/>\n   .antMatchers(&#8216;\/user\/profile&#8217;).hasRole(&#8216;USER&#8217;) \/\/ check for authority with ROLE_USER in the database<br \/>\n   .antMatchers(&#8216;\/user\/**&#8217;).hasRole(&#8216;ADMIN&#8217;) \/\/ check for authority with ROLE_ADMIN in the database<br \/>\n   .and()<br \/>\n   .httpBasic().authenticationEntryPoint(entryPoint)<br \/>\n   .and()<br \/>\n   .exceptionHandling().accessDeniedHandler(handler);<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-45685\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/01\/Screen-Shot-2017-01-29-at-1.50.39-PM.png\" alt=\"Screen Shot 2017-01-29 at 1.50.39 PM\" width=\"1098\" height=\"456\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2017\/01\/Screen-Shot-2017-01-29-at-1.50.39-PM.png 1098w, \/blog\/wp-ttn-blog\/uploads\/2017\/01\/Screen-Shot-2017-01-29-at-1.50.39-PM-300x124.png 300w, \/blog\/wp-ttn-blog\/uploads\/2017\/01\/Screen-Shot-2017-01-29-at-1.50.39-PM-1024x425.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2017\/01\/Screen-Shot-2017-01-29-at-1.50.39-PM-624x259.png 624w\" sizes=\"(max-width: 1098px) 100vw, 1098px\" \/><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-45662\" src=\"\/blog\/wp-ttn-blog\/uploads\/2017\/01\/authenticate-user.gif\" alt=\"authenticate-user\" width=\"1200\" height=\"800\" \/><\/p>\n<p>Hope this will help you to understand the flow for basic authentication using spring security.\u00a0<span style=\"font-weight: 400\">Find the complete code at <\/span><a href=\"https:\/\/github.com\/bjpaul\/restful-spring-security\/blob\/user\/authorization\/src\/main\/java\/org\/basic\/spring\/security\/rest\/service\"><span style=\"font-weight: 400\">GitHub<\/span><\/a><span style=\"font-weight: 400\">.<\/span><\/p>\n<pre class=\"brush: erlang\"><strong>You can\u00a0run the application by below steps,--\r\n<\/strong>\r\n1. git clone <a href=\"mailto:git@github.com\"><span style=\"font-weight: 400\">git@github.com<\/span><\/a><span style=\"font-weight: 400\">:bjpaul\/restful-spring-security.git\r\n2. cd restful-spring-security\r\n3. gradle bootRun\r\n<\/span><\/pre>\n<p>Stay tuned for more on:-<\/p>\n<ul>\n<li style=\"font-weight: 400\">Stateless token based authentication using Spring Security<\/li>\n<li style=\"font-weight: 400\">Domain object security (ACLs)<\/li>\n<li style=\"font-weight: 400\">CAS authentication using spring security<\/li>\n<li style=\"font-weight: 400\">Web socket security in spring<\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">OAuth2 authentication using Spring Security<\/span><\/li>\n<li style=\"font-weight: 400\">Single sign on with OAuth2<\/li>\n<li style=\"font-weight: 400\"><span style=\"font-weight: 400\">Spring security with JWT<\/span><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Spring Security is a lightweight security framework that provides authentication and authorization support in order to secure Spring-based applications. It comes bundled with popular security algorithm implementations. I would cover a series of different topic related to spring security\u00a0in my upcoming blogs. We will go through the setup process first, then analyze when and where [&hellip;]<\/p>\n","protected":false},"author":349,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":23},"categories":[446,1],"tags":[3133,4841,1202,672],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/45203"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/349"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=45203"}],"version-history":[{"count":2,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/45203\/revisions"}],"predecessor-version":[{"id":54490,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/45203\/revisions\/54490"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=45203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=45203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=45203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}