How to communicate from AngularJS based frontend to REST API backend securely - angularjs

I have created REST API with Spring Boot and Single Page Application powered by AngularJS.
The question is how to prevent everyone from using my REST api which is available publicly in the internet? I want it to be allowed for usage only from my webpage.
I can not use any secret/password/token from angular side as it would be visible to anyone.

Spring security can help with that. You can define some urls accessible by only certain users having certain roles.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configures(HttpSecurity http) throws Exception {
http.exceptionHandling()
.accessDeniedPage("/error").and()
.authorizeRequests()
.antMatchers("/api/**").hasAnyRole("USER_ROLE");
}
}
So that, only those with role "USER_ROLE" can access any url starts with "/api".
In order to have this functionality, you have to implement a login system which assign the "USER_ROLE" to the users after successful login.
On AngularJs part, it is quite easy. You just make a http request to the REST api, since the browser holds cookies and JSESSIONID, it will be sent along with the request in the header. Spring picks it up and checks if the user having that JSESSIONID has authority to access the url.

Related

401 Unauthorized calling my Azure Rest API

I have a Rest API using controllers, etc, hosted in Azure that has been working for some time. I want to secure the various methods. I added the API App (.NET core) to the App Registrations, and also added the javascript client app to App Registrations. I believe I'm initializing everything in startup.cs in the REST Api OK. I added [Authorize] to one of the methods. I used a simple javascript example which calls myMSALObj.loginPopup, and gets back a token which I then add to the Authorization header and make a fetch call. When I call, I see HTTP Error 401.0 - Unauthorized in the log stream for my App Service.
Any ideas how I can troubleshoot this to get more specifics about what is wrong?
Also, a related question: in App Registrations, Api Permissions, how does one correlate the API permission name with the method in the controller?
Add this in front of the method in the controller
[AuthorizeForScopes(Scopes = new[] { "My.Scope" })]

Spring Boot application gives "405 method not supported" exception for only Angular/HTML/JSP resources

I have an application written with Spring Boot and AngularJS. When I try to hit a REST service as part of this application, I am able to hit it with POST method wherever POST is configured for request mapping.
But if I try to request AngularJS bind pages, I get a "405 method not supported" exception. So I try to create HTML and JSP pages too, which are not bound to Angular but still, I am getting the same exception.
Where can I start debugging this, and what is the likely reason?
i am sharing here furthere details about issue.
Basically this existing application created/developed with Jhipster, angularjs, Spring boot and spring security does not allow to access html/angularjs related resources with POST from outside. I will explain here what different scenarios work and what is not not working. 1.Postman trying to access base url trying to fetch index.html from same application- Give 405 Post method not allowed.2.Created an independent Test.html in same application and trying to access it from postman- Gives 405 Post method not allowed.3.Created a service which allows POST access in same application- Able to hit service from WSO2 IS IDP and also from Postman.4.Created a separate application on tomcat and provided as callback in WSO2 IDP with starting point for SSO from base url of existing application- Able to hit callback URL on tomcat server. Firefox shows that a POST request was generated for callback URL from WSO2 IS IDP to tomcat based application 5.Created a separate application with Angular js and Spring boot and provided as callback in WSO2 IDP with starting point for SSO from base url of existing application- Able to hit callback URL on tomcat server. Firefox shows that a POST request was generated for callback URL from WSO2 IS IDP to new application with Spring boot and Angularjs. This took me down to conclusion that one of three is causing this issue
1. Spring security generated from JHipster
2. Angularjs
3. Some CORS or other filter from Spring Security is causing this issue.
Till now we have tried to different debugging methods like
1. disable CORS,
2. in angularjs-resource.js enable POST for get operation,
3. In SecurityCOnfigurer, try to permit POST method for base URL or resolve it to GET in httpsercurity authorizerequest etc.
4. Also ignoring resources in websecurity.
Application stack for existing application which we are trying to implement SSO is as below
1. Angularjs 1.5.8
2. Springboot 1.5.9.release
3. WSO2IS 5.4.1
4. WSO2AM 2.1.0
5. JHipster
Let me know if any particular area which we might have missed to analyze or different methods to try.
Thanks,
Sandeep
Try to disable CSRF in security config
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
...
}
...
}
#SpringBootApplication
#Import({
...
SecurityConfig.class
...
})
public class SpringBootApp {
...
}

Spring boot + mvc (rest) + angularJS: add security

I have a web application with separate front and back:
/project
+--- /back
+--- /front
The back is developped using Spring boot + Spring MVC, while the front is using AngularJS.
I am trying to set up the security for the communication between the back/front. What I did:
- create a ConfigSecurity class which extends from WebSecurityConfigurerAdapter
- create a SpringWebMvcInitializer which extends from AbstractAnnotationConfigDispatcherServletInitializer and call ConfigSecurity
- create a SecurityWebInitializer class which extends AbstractSecurityWebApplicationInitializer
My ConfigSecurity looks like this:
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class ConfigSecurity extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/demo/**","/home").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin().loginPage("...")
.and()
.httpBasic();
}
}
My problems:
In configureGlobal(), I can set the username and password to access my protected urls, but how can I do when there is not only one single user? I mean, I want to grant access to all the users that are registered in my database.
Since the back and the front are only communicating with REST (through JSON files), what should be done with formLogin() in ConfigSecurity? By default, Spring Security generates a default login form. I don't need a it in the back of the application since it is the front which is responsible for displaying the loginPage. How can I skip the login page in the back? Maybe by putting the username and password in JSON file the front is sending to the back? Does someone know how it can be done?
I am using Java Configuration for Spring (not XML configuration).
You have many options, all of them require quite a lot of code, but most of it is already well implemented around the internet so you just would have to make it fit your needs. You can either go with simplest way which would be http sessions, JSON token or JWT (JSON web token) or anything else.
Spring blog has a very long post about how to implement different
solutions here:
https://spring.io/guides/tutorials/spring-security-and-angular-js/
JHipster also has different authentication methods which you can take a look at. They have very well implemented role security in front-end which I like a lot and would really suggest looking into: https://github.com/jhipster/jhipster-sample-app
Here's also a JWT which is requires the most code: http://blog.jdriven.com/2014/10/stateless-spring-security-part-2-stateless-authentication/
HTTP Sessions would definitely be the easiest to set up and is well supported by Spring Security out of the box already.
Found great help on this baeldung website (even though it is using XML configuration) and this website (using Java configuration).
For global explanation of how Spring security works, this link helps me a lot.

Siteminder SSO + Spring Security + Angular JS

I have seen lot of examples where, there is a custom Login page with Angular JS, and then we make a rest POST call with the username/pwd, and then Spring authenticates based on whatever Auth Service we provide. Then we receive a success, grab the user object from Spring Security and then create a Session cookie in Angular.
https://github.com/witoldsz/angular-http-auth/blob/master/src/http-auth-interceptor.js
I also have seen, integrating Siteminder with Spring Security where we install a policy agent on the web server, and then grab request headers with Spring Security, and then pull the roles and build a user profile object.
I'm looking for a solution where I can combine both the above. This is the scenario :
When the user requests for index.html (Angular), the policy agent on the web server intercepts, authenticates with a Siteminder login page and then passes the headers to the app server. The Spring Security on app server will read the headers and pull the roles from our app database and then build a userprofile object. Now here, I want to continue the flow and display angular page, but Im trying to figure out, how do I send the user profile object to angular, because angular is not making a POST call at this point. Also, how do I get the http-auth-interceptor in play, because I need to keep checking if the user is still authenticated on the change of every view/state in Angular.
Help appreciated ! Thanks !
You may implement a tiny JSON REST service "/your-app/profile" which is protected by SiteMinder, reads and evaluates the headers and returns the result as a JSON object.
Your Angular App (e.g. /your-app/index.html) should better also be protected by SiteMinder so you receive an immediate redirect to the SSO Login when accessing it without session. In addition, it must read the JSON REST resource "/your-app/profile" when loaded. It must also expect that SMSESSION is missing when reading "/your-app/profile" and react accordingly - perform a reload of the protected index.html page to trigger a SM SSO re-login (if "/your-app/index.html" is protected, otherwise you must trigger login by a redirect to some protected resource).
If you want to constantly check to see if SiteMinder session is still present, you may either access the "/your-app/profile" or check for the presence of the SMSESSION cookie (only in case it is not set as HTTP-only).
One SECURITY NOTE: If you rely on the seamless SSO which is provided via SMSESSION cookie, be aware of the possible CSRF (Cross-Site Request Forgery) attacks!
Apparently both roles and the username will be available in spring if the integration is done as this describes
Integrating Spring Security with SiteMinder

Laravel auth session initiated from a different domain doesn't persist

Is there anyone familiar with s built with running on one domain (laravelapi.com) and apps connecting to it from another domain (angularapp.com)?
How did you handle the authentication session?
Imagine there is a route in the API like /auth/get-user, which does this:
AuthController extends Controller
{
//Accessed through /auth/get-user
public function getUser()
{
return Response::json(Auth::user());
}
}
As long as the app and the API are in the same domain, the above code works fine, but when I move them to separate domains, the API just returns a 401 Unauthorized error.
I have set the above error to be returned when ! Auth::check ().
So simply, Laravel's auth session doesn't persist when requested through another domain. How would you face this issue?

Resources