简体   繁体   中英

Spring Boot and Angular authentication - how to secure the app?

So I have this legacy app running with spring MVC and JSP, Reading from mongo DB
, I am thinking of replacing it with a modern app using Spring boot and angular JS

I am not looking for a framework, My question is more conceptual regarding authentication, and how it works between angular and Spring boot.

I don't want to use a third party for authentication,I would like to continue using my internal DB user and password.
I also have a rest API that clients need to register first and then send a token on every request bypassing angular and authentication.

So in the past ( ancient j2ee ) I had Servlet filter, this filter war running on any request, it checked if the session is authenticated, if not - it would forward to the authentication page, then store the result in the session.

something along the lines of this:

@WebFilter("/*")
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String loginURI = request.getContextPath() + "/login";

        boolean loggedIn = session != null && session.getAttribute("user") != null;
        boolean loginRequest = request.getRequestURI().equals(loginURI);

        if (loggedIn || loginRequest) {
            chain.doFilter(request, response);
        } else {
            response.sendRedirect(loginURI);
        }
    }

    // ...
}

How to do the same authentication mechanism with angular JS?
what is the equivalent to filters in servlets?
since Angular is client side rendering, how to secure it?

Thank you for any input!

The obvious thought: https://spring.io/guides/tutorials/spring-security-and-angular-js/

If you tried to serve angular on the same port using static resources, you will have a hard time setting it up with spring boot because there will be conflicts about who should resolve a particular resource: angular or spring boot. For eg: /home can be resolved by angular but spring isn't aware of the fact that there is a /home and if you hit /home directly, it won't be resolved by angular unless index.html was loaded and you will see a 404 Whitelabel page.

If you serve angular and spring boot on separate ports then you must read this quote from above spring guides:

You can't have a secure, stateless application.

Adding to what Hopey One already pointed out: Using JHipster is not as bad as you think. It will hardly take a day to build 80% of your project and then you can tweak the rest 20% accordingly. It will take care of most of the gaps in knowledge and let you write the code that is actually required. And since you already have a running application, most of it would be a copy-paste work. You can read this guide to set up the environment.

I am not looking for a framework, My question is more conceptual regarding authentication, and how it works between angular and Spring boot.

I found this particular tricky to reply, since you are asking for a conceptual answer beyond particular framework, but you are referring to Angular and Spring which are two frameworks, so let's take one step back.

Proper authentication always has to be performed server side, since authentication on the client is simple to bypass. You can have some watchdogs for disallowing certain routes client side, but just to improve UX.

There are basically two flavours to choose from: state or stateless

State authentication is when after the successful authentication, the server will create some session, store some identifier of it, and validate against it on successive requests. This is the traditional session with cookies approach, named JSESSION in spring. The drawback of this approach is that the state has to be maintained somewhere, and unless you have sticky sessions (where you can get away by keeping this info in memory) you will need some distributed system to store/retrieve it (a SQL db, cassandra, your pet project, etc). But as we learned, distributed state with high traffic turns a bottleneck and is better to avoid it when possible.

Stateless Authentication: As is the case of the JWT contains all the information needed to recreate the session on any server, so there is no distributed state, or better said, the state is in the client (browser), and is cryptographically signed so users can access/tamper them. The drawback is that the encryption/decryption of the token could be a bit CPU demanding, but nothing noticeable for a user.

So once you decided one the above, the rest is not that different. In both cases you will have to implement some interceptor on angular, to send along the cookie or the Auth header on each request depending the case, and on the server side you will have to handle the request thru the corresponding filter. Instead of the cookie in the first example you could just send the session value and as a header, in a more RESTful fashion.

I also have a rest API that clients need to register first and then send a token on every request bypassing angular and authentication.

This looks like a new use case for your API but the above stated holds, you could still use those authentication headers for Authorisation after the login was done and token/sessions were returned to the authenticating user. You could have also a different authentication token for this type of client, in which case it would be just a matter to chain a new filter for checking this header, without any changes on your API.

I'm sure you will find the right resources online to implement your desired authentication/authorisation solution

Have a look at the JHipster project. Without much effort you can generate a simple project built on angular and spring boot. It implements JWT for authentication with a DB of your choice. Might serve as a good bootstrap or as a reference implementation for implementing your project.

I recommend exploring these two topics:

Filter is part of servlet-api , it means that filter can be implemented in any library, and web server will register and map to specific url. In our case your LoginFilter is all most the same like JWTAuthenticationFilter , but with additional functionality of Spring Framework, both of these classes implement the Filter interface.

With Spring Boot your want to use Spring Security and build on top of the framework as much as possible. I see three approaches:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM