how to create password protected web pages in google app engine - google-app-engine

I am developing a website using jsp-servlet in google app engine. I want to secure some web pages from all the users that visit my site. So is there any way to password protect my web pages. I know it is easily done by htaccess in apache. Can htaccess work in google app engine? if Yes, please specify the process.

You can take advantage of the App Engine Users API. This allows users to log in to your app using their Google account. If you want to control who can get into what parts of your app, you could check the logged-in user's ID against a list of allowed users in your data store when they make a request to your servlet.
Edit:
You're not going to find a method exactly like using .htaccess files -- that's just not how App Engine works. You have code in your servlets that are responsible for rendering pages. In this code, you'll need to add a check to see if the user has access, but only for the pages that you'd like to check.
Here's a code sample, which I hope might clarify things. This is a slightly-modified version of the code at the link I sent you.
public class MySecretServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
UserService userService = UserServiceFactory.getUserService();
resp.setContentType("text/html");
if (req.getPathInfo().equals("/secret_page") {
if (req.getUserPrincipal() != null &&
req.getUserPrincipal().getUserId().equals("admin-id")) {
// render your protected page here
} else {
resp.getWriter().println("<p>Please <a href=\"" +
userService.createLoginURL(thisURL) +
"\">sign in</a>.</p>");
}
} else {
// render your unprotected content here
}
}
}
Alternatively, you can use the security constraint features in your web.xml file. You can find the documentation for those here. This is less flexible, though, as you can only change access rights between "everyone" and "admin-only".

Related

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

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.

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.

Authentication on Google App Engine (web page)

I would like to require the user to use a login/password when accessing some parts of my GAE (Google App Engine) application. I want to limit the access to the set of predefined users, e.g. on the page, where new data can be uploaded to the Datastore.
I found there are 3 ways on GAE how this can be solved, but it looks like only the last one (the most complicated) could be a solution for my issue:
Use a deployment descriptor (<security-constraint> in web.xml). This is not nice, since those users have access, even as viewers to the GAE application's admin page, where they can see the billing history, browse Datastore, logs, etc. and this is something I have to avoid.
Use the federated login (Open ID) (https://developers.google.com/appengine/articles/openid) and allow users to use their Google, Yahoo! or other identities to login. It is not a solution, since I want to limit the access to a small set of users (max. 5) and not allow everybody to use the application.
The other option is to create simple custom login page accessible only via HTTPS and let the user send the username & password in a POST request (it can be plain since we have secure https connection) to a servlet, on the servlet generate some session identifier with specified validity and make it part of every subsequent request. It also needs to check each time the user sends a GET or POST request if the session identifier exists and does not expire meanwhile manually.
Any other/better proposals on how to maintain administrator accounts? Can HttpSession help with the last variant?
Kind Regards,
STeN
I suggest the standard Google login page. Use something like this in you authentication controller (Java + Jersey Framework which is of course not necessary):
#Path("/login")
public Response login(#Context UriInfo ui) throws Exception {
UserService userService = UserServiceFactory.getUserService();
com.google.appengine.api.users.User user = userService.getCurrentUser();
Response response;
if (user == null) {
URI uri = new URI(userService.createLoginURL(ui.getBaseUri().toString()));
response = Response.seeOther(uri).build();
} else {
URI uri = new URI("/");
response = Response.seeOther(uri).build();
}
return response;
}
#GET
#Path("/logout")
public Response logout(#Context UriInfo ui) throws Exception {
UserService userService = UserServiceFactory.getUserService();
com.google.appengine.api.users.User user = userService.getCurrentUser();
Response response;
if (user == null) {
URI uri = new URI("/");
response = Response.seeOther(uri).build();
} else {
URI uri = new URI(userService.createLogoutURL(ui.getBaseUri().toString()));
response = Response.seeOther(uri).build();
}
return response;
}
The login method redirects you app to the Google login page if the user is missin (essentially not logged in). The logout method will logout the user.
Hope this helps
I use a combination of 2 and 3. I allow all users to login, but then I limit actions to particular e-mail addresses. These could be hard coded or (better) in the datastore and memcache (so that you don't have to query the datastore on every request). You could also cache this data in static variables in Java if you want to - just be aware that you might need to kill instances off manually if you change the users who have access. If, like me, you rarely / never change access then this shouldn't be a problem.
Allowing all users to login really gives them no access in my app - they see the admin pages but they're empty apart from a message saying "You do not have access to any of these administrative options".
Some notes:
AFAIK your assumption is not correct. Login to application has nothing to do with admin pages permission. You need to explicitly add users via "Permissions" page for them to have access to admin pages.
You can still check user properties (email) after user logs in with OpenID and deny them access.
This is of course doable. The natural way to track users are sessions. Google for examples.
In both cases 2. ' 3. it's advisable to have a servlet filter that checks session if there is user logged in and deny access (return 404) if user is not logged in.
Pay attention to the 3rd solution: instead of passing username & password my webapp asks username & apiSecret (generated automatically at the first login), so you can invalidate (and re-generate) quickly the apiSecret if something goes wrong.
There is another option: OAuth (https://developers.google.com/appengine/docs/java/oauth/).
Here is my piece of code (UserAccount is my class to represent a User; User is "com.google.appengine.api.users.User", retrieveUser(..) is the function to retrieve my UserAccount from a logged "User"):
public UserAccount getUserLogged(HttpServletRequest request) {
try {
User loggedUser = oauthService.getCurrentUser();
if(loggedUser!=null) {
return super.userAB.retrieveUser(loggedUser);
}
} catch (OAuthRequestException e) {
return null;
}
return null;
}

Appengine user service +GWT not logging out

I have an appengine app with a GWT frontend. I am using appengine's user service to authenticate with google accounts. My problem is when logging out from the GWT frontend the user is not completely logged out. The user is shown the login page, however when you click to login again with google a google account, it goes straight to the app without going to the google login page. I am not using any custom login/pass fields here, strictly appengine user service.
I am guessing this has something to do with HTTP sessions and basic authentication, however I have not been able to log out entirely.
Here is the Login/out service on the server:
import javax.servlet.http.HttpSession;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
#SuppressWarnings("serial")
public class LoginServiceImpl extends RemoteServiceServlet implements
LoginService {
public final static String CHANNEL_ID = "channel_id";
#Override
public UserAccountDTO getLoggedInUserDTO() {
UserAccountDTO userDTO;
HttpSession session = getThreadLocalRequest().getSession();
UserAccount u = LoginHelper.getLoggedInUser(session, null);
if (u == null)
return null;
userDTO = UserAccount.toDTO(u);
UserService userService = UserServiceFactory.getUserService();
userDTO.setLogoutURL(userService.createLogoutURL(requestUri));
return userDTO;
}
#Override
public void logout() throws NotLoggedInException {
getThreadLocalRequest().getSession().invalidate();
throw new NotLoggedInException("Logged out");
}
}
On the GWT client side I am using this code to logout:
Window.Location.assign(currentUserDTO.getLogoutURL());
When I click the logout link on my app (which runs the code above), nothing changes. However If I reload the page I am sent to my app's login page. When I click to login with my google account it goes straight into my app without asking for google credentials. This is tells me the user was logged out from my appengine app, however the the user is still somehow logged in to his google account in the browser (I'm assuming an auth token stored as a cookie?). I need to have my users completely logged out of there google account so the next visitor to the site is asked for google credentials.
Ideally to LogOut from GAE/Google I would use logOutUrl coming out of userService. For example
UserService userService = UserServiceFactory.getUserService();
logOutURL = userService.createLogoutURL(baseURL);
logOutURL is where I would redirect window to, to log out from Google
Also check a small servlet I have written to login and logout at: http://cloudspring-demo.appspot.com/html/csAuth.html
You can simply copy this servlet in appropriate servlet and after adding mapping in web.xml, you can simply invoke it to test out.

Require users to complete profile following successful authentication

I'm developing a standalone custom registry, custom login portlet, and custom profile portlet for Websphere Portal 6.1. Some existing users have not completed one or more required fields in their profiles.
The next time these users log in successfully, how can I get the portal to redirect them to the custom profile portlet before giving them access to the rest of the site?
It looks like Websphere Portal 6.1 comes with an API for sending authentication requests through a chain of filters. I found an article describing the API on developer works ('New security APIs in Websphere Portal').
In particular, the com.ibm.portal.auth.ExplicitLoginFilter interface lets you plug in during the authentication sequence and dynamically change where the system redirects after the user's credentials are validated. Here is a stubbed example:
public class CustomLoginFilter implements ExplicitLoginFilter {
public void login(HttpServletRequest req, HttpServletResponse resp,
String userId, char[] password,
FilterChainContext portalLoginContext, Subject subject,
String realm, ExplicitLoginFilterChain chain)
throws LoginException, WSSecurityException,
com.ibm.portal.auth.exceptions.LoginException {
//Validate the user's credentials.
chain.login(req, resp, userId, password, portalLoginContext, subject, realm);
//Redirect to profile portlet if required profile fields are incomplete.
if(incompleteProfile(userId)) {
portalLoginContext.setRedirectURL(getURLForProfilePortlet());
}
}
//Other methods...
}
The ExplicitLoginFilter and its dependencies are located in the following jar files, which you must add to your classpath when compiling your code:
Starting from your Websphere Portal root directory...
/base/wp.auth.base/shared/app/wp.auth.base.jar
/base/wp.base/shared/app/wp.base.jar

Resources