{"id":3946,"date":"2020-09-29T03:52:15","date_gmt":"2020-09-29T03:52:15","guid":{"rendered":"https:\/\/codethataint.com\/blog\/?p=3946"},"modified":"2020-10-03T17:55:53","modified_gmt":"2020-10-03T17:55:53","slug":"spring-security-configuring-authentication","status":"publish","type":"post","link":"https:\/\/codethataint.com\/blog\/spring-security-configuring-authentication\/","title":{"rendered":"Spring Security Configuring Authentication and Authorization"},"content":{"rendered":"<p><strong>ApplicationSecurityConfig.java<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Configuration\r\n@EnableWebSecurity\r\npublic class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {\r\n    @Override\r\n    protected void configure(HttpSecurity httpSecurity) throws Exception{\r\n        httpSecurity.authorizeRequests()\r\n                    .anyRequest()\r\n                    .authenticated()\r\n                    .and()\r\n                    .httpBasic();\r\n    }\r\n}\r\n<\/pre>\n<p><strong class=\"ctaHeader3\">Whitelisting some URLs(index, js and CSS files)<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Configuration\r\n@EnableWebSecurity\r\npublic class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {\r\n    @Override\r\n    protected void configure(HttpSecurity httpSecurity) throws Exception{\r\n        httpSecurity.authorizeRequests()\r\n                    \/\/Whitelisting URLS\r\n                    .antMatchers(&quot;\/&quot;, &quot;index&quot;, &quot;\/css\/*&quot;, &quot;\/js\/*&quot;).permitAll()\r\n                    .anyRequest()\r\n                    .authenticated()\r\n                    .and()\r\n                    .httpBasic();\r\n    }\r\n}\r\n<\/pre>\n<p><strong>Authentication with password with no encryption<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Override\r\n@Bean\r\n protected UserDetailsService userDetailsService() {\r\n       UserDetails mugilUsrBuilder = User.builder()\r\n              .username(&quot;Mugil&quot;)\r\n              .password(&quot;{noop}password&quot;)\r\n              .roles(&quot;ADMIN&quot;)\r\n              .build();\r\n\r\n      return new InMemoryUserDetailsManager(mugilUsrBuilder);\r\n}\r\n<\/pre>\n<p>If {noop} is not used in password Spring security would throw an error asking to encode the password with password encoder as below.<br \/>\n<em>java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id &#8220;null&#8221;<\/em><\/p>\n<p><strong class=\"ctaHeader3\">Using Password Simple Encoder<\/strong><br \/>\n<strong>PasswordConfig.java<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Configuration\r\npublic class PasswordConfig {\r\n    @Bean\r\n    public PasswordEncoder passwordEncoder()\r\n    {\r\n        return new BCryptPasswordEncoder(10);\r\n    }\r\n}\r\n<\/pre>\n<p><strong>ApplicationSecurityConfig.java<\/strong><\/p>\n<ol>\n<li>Inject the passwordEncoder from PasswordConfig class to ApplicationSecurityConfig<\/li>\n<li>Encode the password using instance of injected encoder in ApplicationSecurityConfig<\/li>\n<\/ol>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n @Autowired\r\n    private PasswordEncoder passwordEncoder;\r\n\r\n    @Autowired\r\n    public ApplicationSecurityConfig(PasswordEncoder passwordEncoder) {\r\n        this.passwordEncoder = passwordEncoder;\r\n    }\r\n\r\n    @Override\r\n    @Bean\r\n    protected UserDetailsService userDetailsService() {\r\n        UserDetails mugilUsrBuilder = User.builder()\r\n                .username(&quot;Mugil&quot;)\r\n                .password(this.passwordEncoder.encode(&quot;password&quot;))\r\n                .roles(&quot;ADMIN&quot;)\r\n                .build();\r\n\r\n        return new InMemoryUserDetailsManager(mugilUsrBuilder);\r\n    }\r\n<\/pre>\n<p><strong class=\"ctaHeader3\">Allowing Access to API based on Role &#8211; Authorization<\/strong><br \/>\n<strong>ApplicationSecurityConfig.java<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Configuration\r\n@EnableWebSecurity\r\npublic class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {\r\n.\r\n.\r\n @Override\r\n    @Bean\r\n    \/\/Authentication\r\n    protected UserDetailsService userDetailsService() {\r\n        UserDetails adminUsrBuilder = User.builder()\r\n                .username(&quot;admin&quot;)\r\n                .password(this.passwordEncoder.encode(&quot;password&quot;))\r\n                .roles(&quot;ADMIN&quot;)\r\n                .build();\r\n\r\n        UserDetails regularUsrBuilder = User.builder()\r\n                .username(&quot;user&quot;)\r\n                .password(this.passwordEncoder.encode(&quot;password&quot;))\r\n                .roles(&quot;USER&quot;)\r\n                .build();\r\n\r\n        return new InMemoryUserDetailsManager(adminUsrBuilder, regularUsrBuilder);  \r\n    }\r\n\r\n    @Override\r\n    \/\/Authorization\r\n    protected void configure(HttpSecurity httpSecurity) throws Exception{\r\n        httpSecurity.authorizeRequests()\r\n                     \/\/Whitelisting URLS\r\n                    .antMatchers(&quot;\/&quot;, &quot;index&quot;, &quot;\/css\/*&quot;, &quot;\/js\/*&quot;).permitAll()\r\n                    .antMatchers(&quot;\/api\/**&quot;).hasRole(&quot;ADMIN&quot;)\r\n                    .anyRequest()\r\n                    .authenticated()\r\n                    .and()\r\n                    .httpBasic();\r\n    }\r\n.\r\n.\r\n<\/pre>\n<ol>\n<li>In the above code we have added two roles &#8211; ADMIN and USER<\/li>\n<li>Both were authenticated to access the application.But to access the API the role should be ADMIN\n<pre>\r\n  antMatchers(\"\/api\/**\").hasRole(\"ADMIN\")\r\n<\/pre>\n<\/li>\n<li>If the user with Role USER try to access API then it would end up in 403 &#8211; Forbidden Error<\/li>\n<\/ol>\n<p><strong>Access Allowed<\/strong><br \/>\n<img decoding=\"async\" src=\"https:\/\/codethataint.com\/blog\/wp-content\/uploads\/2020\/09\/AdminAccess.jpg\" alt=\"\" \/><\/p>\n<p><strong>Forbidden Access<\/strong><br \/>\n<img decoding=\"async\" src=\"https:\/\/codethataint.com\/blog\/wp-content\/uploads\/2020\/09\/ForbiddenAccess.jpg\" alt=\"\" \/><\/p>\n<p><strong class=\"ctaHeader3\">Allowing Access based on 2 Different Role <\/strong><br \/>\n<strong>ApplicationSecurityConfig.java<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Configuration\r\n@EnableWebSecurity\r\npublic class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {\r\n.\r\n.\r\n\r\n    @Override\r\n    @Bean\r\n    protected UserDetailsService userDetailsService() {\r\n        UserDetails adminUsrBuilder = User.builder()\r\n                .username(&quot;admin&quot;)\r\n                .password(this.passwordEncoder.encode(&quot;password&quot;))\r\n                .roles(&quot;ADMIN&quot;)\r\n                .build();\r\n\r\n        UserDetails regularUsrBuilder = User.builder()\r\n                .username(&quot;user&quot;)\r\n                .password(this.passwordEncoder.encode(&quot;password&quot;))\r\n                .roles(&quot;USER&quot;)\r\n                .build();\r\n\r\n        return new InMemoryUserDetailsManager(adminUsrBuilder, regularUsrBuilder);\r\n    }\r\n\r\n    @Override\r\n    protected void configure(HttpSecurity httpSecurity) throws Exception{\r\n        httpSecurity.csrf().disable()\r\n                     .authorizeRequests()\r\n                     \/\/Whitelisting URLS\r\n                    .antMatchers(&quot;\/&quot;, &quot;index&quot;, &quot;\/css\/*&quot;, &quot;\/js\/*&quot;).permitAll()\r\n                    .antMatchers(HttpMethod.GET,&quot;\/api\/**&quot;).permitAll()\r\n                    .antMatchers(HttpMethod.DELETE,&quot;\/api\/**&quot;).hasRole(&quot;ADMIN&quot;)\r\n                    .antMatchers(HttpMethod.PUT,&quot;\/api\/**&quot;).hasRole(&quot;ADMIN&quot;)\r\n                    .antMatchers(HttpMethod.POST,&quot;\/api\/**&quot;).hasRole(&quot;ADMIN&quot;)\r\n                    .anyRequest()\r\n                    .authenticated()\r\n                    .and()\r\n                    .httpBasic();\r\n    }\r\n}\r\n<\/pre>\n<ol>\n<li>In the above piece of code we have defined two roles ADMIN and USER<\/li>\n<li>Those with USER role can access the API with HTTP Get Method. That means both ADMIN and USER role could access all the API using GET method\n<pre>\r\n.\r\n.antMatchers(HttpMethod.GET,\"\/api\/**\").permitAll()\r\n.\r\n<\/pre>\n<\/li>\n<li>\nThose with ADMIN role can access the API with HTTP POST, DELETE and PUT Method which corresponds to Create, Delete and Update as per Open API Specifiaction. <\/p>\n<pre>\r\n.\r\n.antMatchers(HttpMethod.DELETE,\"\/api\/**\").hasRole(\"ADMIN\")\r\n.antMatchers(HttpMethod.PUT,\"\/api\/**\").hasRole(\"ADMIN\")\r\n.antMatchers(HttpMethod.POST,\"\/api\/**\").hasRole(\"ADMIN\")\r\n.\r\n<\/pre>\n<\/li>\n<li>The above could be cross checked by changing postman call with HttpMethods and Credentials<\/li>\n<\/ol>\n<p><strong>StudentsService.java<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@RestController\r\n@RequestMapping(&quot;\/api\/v1\/students&quot;)\r\npublic class StudentsService {\r\n    @Autowired\r\n    StudentRepo studentRepo;\r\n\r\n    @GetMapping(path=&quot;{studentId}&quot;)\r\n    public Student getStudentById(@PathVariable(&quot;studentId&quot;) String studentId){\r\n        return studentRepo.getStudentById(studentId);\r\n    }\r\n\r\n    @GetMapping\r\n    public List&lt;Student&gt; getStudentList(){\r\n        return studentRepo.getStudentsList();\r\n    }\r\n\r\n    @PutMapping\r\n    public String updateStudent(@RequestBody Student student){\r\n        return studentRepo.updateStudent(student);\r\n    }\r\n\r\n    @PostMapping\r\n    public String addStudent(@RequestBody Student student){\r\n        if(studentRepo.addStudents(student))\r\n            return  &quot;Student with Id &quot; + student.getStudentId() + &quot; added successfully&quot;;\r\n        else\r\n            return  &quot;Error:Unable to create Student&quot;;\r\n    }\r\n\r\n    @DeleteMapping(path=&quot;{studentId}&quot;)\r\n    public String deleteStudent(@PathVariable(&quot;studentId&quot;) String studentId){\r\n        studentRepo.deleteStudent(studentId);\r\n        return &quot;Student Deleted Successfully&quot;;\r\n    }\r\n}\r\n<\/pre>\n<p><strong class=\"ctaHeader3\">Allowing Access based on 2 Different Authority(or)Permission<\/strong><\/p>\n<ol>\n<li>In the below code instead of using ROLES to authorize users to do something we use AUTHORITIES to allow user<\/li>\n<li>There are two ways to do this. One is by using <em>hasAuthority<\/em> in <em>configure(HttpSecurity httpSecurity)<\/em> method as below  <\/li>\n<li>\n<pre>\r\n.\r\n@EnableGlobalMethodSecurity(prePostEnabled = true)\r\n.\r\n.antMatchers(HttpMethod.POST,\"\/api\/v1\/students\/\").hasAuthority(\"WRITE\")\r\n.antMatchers(HttpMethod.DELETE,\"\/api\/v1\/students\/**\").hasAuthority(\"WRITE\")\r\n.antMatchers(HttpMethod.PUT,\"\/api\/v1\/students\/\").hasAuthority(\"WRITE\")\r\n.\r\n<\/pre>\n<\/li>\n<li>Other is by using @preauthorize annotation to decide the methods<br \/>\nwhich could be allowed access to<\/p>\n<pre>\r\n.\r\n.\r\n@PreAuthorize(\"hasAuthority('READ')\")\r\npublic List<Student> getStudentList(){\r\n.\r\n\r\n@PreAuthorize(\"hasAuthority('WRITE')\")\r\npublic String updateStudent(@RequestBody Student student){\r\n.\r\n.\r\n<\/pre>\n<\/li>\n<\/ol>\n<p><strong>ApplicationSecurityConfig.java<\/strong><br \/>\n<em>Using hasAuthority<\/em><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Configuration\r\n@EnableWebSecurity\r\npublic class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {\r\n\r\n    @Autowired\r\n    private PasswordEncoder passwordEncoder;\r\n\r\n    @Autowired\r\n    public ApplicationSecurityConfig(PasswordEncoder passwordEncoder) {\r\n        this.passwordEncoder = passwordEncoder;\r\n    }\r\n\r\n    @Override\r\n    @Bean\r\n    protected UserDetailsService userDetailsService() {\r\n        GrantedAuthority&#x5B;] arrGrantedAuthAdmin = {new SimpleGrantedAuthority(&quot;READ&quot;), new SimpleGrantedAuthority(&quot;WRITE&quot;)};\r\n        GrantedAuthority&#x5B;] arrGrantedAuthUser = {new SimpleGrantedAuthority(&quot;READ&quot;)};\r\n\r\n        UserDetails adminUsrBuilder = User.builder()\r\n                .username(&quot;admin&quot;)\r\n                .password(this.passwordEncoder.encode(&quot;password&quot;))\r\n                .authorities(&quot;READ&quot;, &quot;WRITE&quot;)\r\n                .build();\r\n\r\n        UserDetails regularUsrBuilder = User.builder()\r\n                .username(&quot;user&quot;)\r\n                .password(this.passwordEncoder.encode(&quot;password&quot;))\r\n                .authorities(&quot;READ&quot;)\r\n                .build();\r\n\r\n        return new InMemoryUserDetailsManager(adminUsrBuilder, regularUsrBuilder);\r\n    }\r\n\r\n    @Override\r\n    protected void configure(HttpSecurity httpSecurity) throws Exception{\r\n        httpSecurity.csrf().disable()\r\n                     .authorizeRequests()\r\n                     .antMatchers(&quot;\/&quot;, &quot;index&quot;, &quot;\/css\/*&quot;, &quot;\/js\/*&quot;).permitAll()\r\n                    .antMatchers(HttpMethod.POST,&quot;\/api\/v1\/students\/&quot;).hasAuthority(&quot;WRITE&quot;)\r\n                    .antMatchers(HttpMethod.DELETE,&quot;\/api\/v1\/students\/**&quot;).hasAuthority(&quot;WRITE&quot;)\r\n                    .antMatchers(HttpMethod.PUT,&quot;\/api\/v1\/students\/&quot;).hasAuthority(&quot;WRITE&quot;)\r\n                    .anyRequest()\r\n                    .authenticated()\r\n                    .and()\r\n                    .httpBasic();\r\n    }\r\n}\r\n<\/pre>\n<p><strong>ApplicationSecurityConfig.java<\/strong><br \/>\n<em>Using @PreAuthorize and EnableGlobalMethodSecurity<\/em><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Configuration\r\n@EnableWebSecurity\r\n@EnableGlobalMethodSecurity(prePostEnabled = true)\r\npublic class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {\r\n\r\n    @Autowired\r\n    private PasswordEncoder passwordEncoder;\r\n\r\n    @Autowired\r\n    public ApplicationSecurityConfig(PasswordEncoder passwordEncoder) {\r\n        this.passwordEncoder = passwordEncoder;\r\n    }\r\n\r\n    @Override\r\n    @Bean\r\n    protected UserDetailsService userDetailsService() {\r\n        GrantedAuthority&#x5B;] arrGrantedAuthAdmin = {new SimpleGrantedAuthority(&quot;READ&quot;), new SimpleGrantedAuthority(&quot;WRITE&quot;)};\r\n        GrantedAuthority&#x5B;] arrGrantedAuthUser = {new SimpleGrantedAuthority(&quot;READ&quot;)};\r\n\r\n        UserDetails adminUsrBuilder = User.builder()\r\n                .username(&quot;admin&quot;)\r\n                .password(this.passwordEncoder.encode(&quot;password&quot;))\r\n                .authorities(&quot;READ&quot;, &quot;WRITE&quot;)\r\n                .build();\r\n\r\n        UserDetails regularUsrBuilder = User.builder()\r\n                .username(&quot;user&quot;)\r\n                .password(this.passwordEncoder.encode(&quot;password&quot;))\r\n                .authorities(&quot;READ&quot;)\r\n                .build();\r\n\r\n        return new InMemoryUserDetailsManager(adminUsrBuilder, regularUsrBuilder);\r\n    }\r\n\r\n    @Override\r\n    protected void configure(HttpSecurity httpSecurity) throws Exception{\r\n        httpSecurity.csrf().disable()\r\n                     .authorizeRequests()\r\n                    .antMatchers(&quot;\/&quot;, &quot;index&quot;, &quot;\/css\/*&quot;, &quot;\/js\/*&quot;).permitAll()\r\n                    .anyRequest()\r\n                    .authenticated()\r\n                    .and()\r\n                    .httpBasic();\r\n    }\r\n}\r\n<\/pre>\n<p><strong>StudentsService.java<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@RestController\r\n@RequestMapping(&quot;\/api\/v1\/students&quot;)\r\npublic class StudentsService {\r\n    @Autowired\r\n    StudentRepo studentRepo;\r\n\r\n    @GetMapping(path=&quot;{studentId}&quot;)\r\n    public Student getStudentById(@PathVariable(&quot;studentId&quot;) String studentId){\r\n        return studentRepo.getStudentById(studentId);\r\n    }\r\n\r\n    @GetMapping\r\n    @PreAuthorize(&quot;hasAuthority('READ')&quot;)\r\n    public List&lt;Student&gt; getStudentList(){\r\n        return studentRepo.getStudentsList();\r\n    }\r\n\r\n    @PutMapping\r\n    @PreAuthorize(&quot;hasAuthority('WRITE')&quot;)\r\n    public String updateStudent(@RequestBody Student student){\r\n        return studentRepo.updateStudent(student);\r\n    }\r\n\r\n    @PostMapping\r\n    @PreAuthorize(&quot;hasAuthority('WRITE')&quot;)\r\n    public String addStudent(@RequestBody Student student){\r\n        if(studentRepo.addStudents(student))\r\n            return  &quot;Student with Id &quot; + student.getStudentId() + &quot; added successfully&quot;;\r\n        else\r\n            return  &quot;Error:Unable to create Student&quot;;\r\n    }\r\n\r\n    @DeleteMapping(path=&quot;{studentId}&quot;)\r\n    @PreAuthorize(&quot;hasAuthority('WRITE')&quot;)\r\n    public String deleteStudent(@PathVariable(&quot;studentId&quot;) String studentId){\r\n        studentRepo.deleteStudent(studentId);\r\n        return &quot;Student Deleted Successfully&quot;;\r\n    }\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>ApplicationSecurityConfig.java @Configuration @EnableWebSecurity public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception{ httpSecurity.authorizeRequests() .anyRequest() .authenticated() .and() .httpBasic(); } } Whitelisting some URLs(index, js and CSS files) @Configuration @EnableWebSecurity public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception{ httpSecurity.authorizeRequests() \/\/Whitelisting URLS .antMatchers(&quot;\/&quot;, &quot;index&quot;, &quot;\/css\/*&quot;, &quot;\/js\/*&quot;).permitAll() .anyRequest() .authenticated() .and()&hellip; <a href=\"https:\/\/codethataint.com\/blog\/spring-security-configuring-authentication\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[325],"tags":[],"class_list":["post-3946","post","type-post","status-publish","format-standard","hentry","category-spring-security"],"_links":{"self":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts\/3946","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/comments?post=3946"}],"version-history":[{"count":5,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts\/3946\/revisions"}],"predecessor-version":[{"id":3963,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/posts\/3946\/revisions\/3963"}],"wp:attachment":[{"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/media?parent=3946"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/categories?post=3946"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codethataint.com\/blog\/wp-json\/wp\/v2\/tags?post=3946"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}