How can I make a field public in AWS Amplify graphql schema? - amazon-cognito

I am writing an AWS amplify graphql schema for a set of users. I want the usernames to be public (so anyone can search and find users by username) and the user's info (descriptions, etc) to be private (only followers can see).
I know how to use #auth to setup the private data, but how can I make usernames public?

Looks like this PR will implement this https://github.com/aws-amplify/amplify-cli/pull/1916

You can allow public schema access by ApiKey but have restricted fields using #aws_iam decorator
type Post #aws_api_key {
id: ID!
author: String
title: String
content: String
url: String
ups: Int!
downs: Int!
version: Int!
restrictedContent: String!
#aws_iam
}
https://github.com/aws/aws-appsync-community/issues/1

Related

Is Spring Data LDAP generally intended for bind authentication?

I am trying to use Spring Data LDAP for users authentication using OpenLDAP server. However, search by uid and userPassword fails because the password is stored as SSHA hashed.
I wonder if really Spring Data LDAP can be used for users authentication because the tutorials usually concentrate on searching or they map password to some attribute other than userPassword.
#Entry(base = "ou=People", objectClasses = { "top", "person", "inetOrgPerson", "organizationalPerson", "simpleSecurityObject" })
public class LdapUser {
#Id Name dn;
#Attribute(name = "userPassword")
private String password;
/** The user id. */
#Attribute(name = "uid")
private String userName;
}
public interface ILdapUserRepo extends LdapRepository<LdapUser>{
public LdapUser findByUserNameAndPassword(String username, String password);
}
Your use-case isn't what Spring Data LDAP is intended for. Spring Data LDAP is intended to lookup objects from LDAP by querying these and updating LDAP entities.
Performing LDAP authentication requires authentication against LDAP directly by using the appropriate connectors.

Spring security WSO2 IS integration - Figure out how to assign authorities/customize wso2 token

I am very stuck with this issue for a couple of days.
So what I am trying to do is to assign ROLES with spring security framework. My goal is to decode token that I get from WSO2 Identity Server 5.0 through openid and assign the Role so I can authorize the request based on Roles (AUTHORITIES)
This is my SecurityConfig class in simple spring boot app
#Profile("oauth")
#Configuration
#EnableResourceServer
public class SecurityConfig {
}
So, with this configuration, I am able to decode the token.
However, in debug mode, when I made a request with the id_token to the simple spring boot app, I received an error:
java.lang.ClassCastException
java.lang.String cannot be cast to java.util.Collection
And it happens in DefaultAccessTokenConverter class, particularly in the line of code when the map object is converted to String [] roles
public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
...
if (user==null && map.containsKey(AUTHORITIES)) {
#SuppressWarnings("unchecked")
String[] roles = ((Collection<String>)map.get(AUTHORITIES)).toArray(new String[0]);
authorities = AuthorityUtils.createAuthorityList(roles);
}
OAuth2Request request = new OAuth2Request(parameters, clientId, authorities, true, scope, resourceIds, null, null,
null);
return new OAuth2Authentication(request, user);
}
This is my WSO2 decoded token
{
"auth_time": 1464819792,
"exp": 1464823490,
"azp": "U1PXsuyV_tdBERmZIoHHnqoGkWIa",
"authorities": "[\"ROLE_ADMIN\",\"approver\",\"Internal\/everyone\"]",
"at_hash": "Hh2LUZl3Bp6yDqyZt4r6Gg",
"aud": [
"U1PXsuyV_tdBERmZIoHHnqoGkWIa"
],
"iss": "https://localhost:9443/oauth2/token",
"locality": "[\"ROLE_ADMIN\"]",
"iat": 1464819890
}
It seems that Spring expects Array of String, not String object (there is a double quote at the beginning and the end of value in authorities.
The aud format seems to be what the spring expects.
So, there are two options I can think o
1. Write some configuration in Spring Oauth2 (I have not figured this out yet)
2. Configure WSO2 Identity Server (This what I've been trying to do).
There are some resources saying that we can implement our own JWTTokenGenerator in WSO2 carbon. From looking at the code, it seems this is where the double quotes are generated in the claim.
org.wso2.carbon.identity.oauth2.authcontext.JWTTokenGenerator
I hope there is someone else who has been going through this.
Thank you very much.
Please find the default implementation here [1]. Also it is better if you can go with IS 5.1.0 for 5.1.0 refer [2]. After building custom JWTTokenGenerator copy it to repository/components/lib. Change
<TokenGeneratorImplClass>
element in identity.xml according to your custom implementation.
[1] https://svn.wso2.org/repos/wso2/carbon/platform/branches/turing/components/identity/org.wso2.carbon.identity.oauth/4.2.3/src/main/java/org/wso2/carbon/identity/oauth2/authcontext/JWTTokenGenerator
[2]https://github.com/wso2/carbon-identity/tree/master/components/oauth/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/authcontext
Thank you! That could work too! but for easier implementation, we use 5.2.0 beta version that that produce array of string. T

Regenerating password hash during user authentication with Symfony

I'm using Symfony3 and FOSUserBundle and have the below code which enables member entities (that are from a migrated database) to log in with their usual password by using my class "clubEncoder" instead of Symfony's default bcrypt. "clubEncoder" is working fine (as below) for logging members in. Ideally I want to be able to do the following in the background:
Try to authenticate the user using bcrypt
If that fails, then try to authenticate again using the "clubEncoder" class
If a user is authenticated using "clubEncoder" then the password hash in the database should be re-generated using bcrypt (so step #1 works).
My questions:
I assume I need to change my security.yml to specify both encoders. However, the articles I've read only describe using different encoders for handling different subsets of users - whereas I want to try them both on all users...can this still be done?
To regenerate the password hash in the database, I'm assuming the controller needs to be changed however as I'm using FOSUserBundle I do not have the routes to customise. Is this the wrong place to be looking to add the code?
** Below is the code I currently have stable and working for step #2:
config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
fos_user:
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\Member
security.yml
security:
encoders:
AppBundle\Entity\Member:
id: club.member_encoder
// AppBundle\Entity\Member:
// id: bcrypt
parameters.yml
services:
club.member_encoder:
class: AppBundle\Service\clubEncoder
clubEncoder.php
namespace AppBundle\Service;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
class clubEncoder extends \Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder implements PasswordEncoderInterface
{
function __construct($cost=13)
{
parent::__construct($cost);
}
function isPasswordValid($encoded, $raw,$salt)
{
if (parent::isPasswordValid($cost=13, $encoded,$raw,$salt)) return true ;
else if ($this->comparePasswords($encoded, sha1("3^1nD".$raw."Hx&&%"))) {
// ADD SOMETHING HERE TO RE-HASH THE PASSWORD TO BCRYPT???????????????????
return !$this->isPasswordTooLong($raw) &&
$this->comparePasswords($encoded, sha1("ThisIsSaltA".$raw."ThisIsSaltB"));
}
}
}

Apache Shiro - LDAP for Authentication and Properties/Ini for Authorization

i´m trying to add some authentication and authorization functionality to my small web application. therefore i´m using apache shiro.
my plan: using an existing ldap server for user authentication and using a properties or ini file for authorization.
here´s a small example:
user x wants to use the application
he enters his username and his password
the ldap server is used for authentication --> user + pwd correct?
if authentication is verified and correct, a properties file or ini file is used to check if the user is permitted, to start some functions inside the application.
i hope you know what i´m trying to do.
now i´m not sure how to implement this feature. is it enough to use an ini file or is it required to implement my own realm?! is there an example implementation?
i´m grateful for every information
and sorry for my bad english :/
Yes, you have to implement a realm but this is not difficult. You just have to extend JndiLdapRealm and override the queryForAuthorizationInfo method.
This method returns an AuthorizationInfo interface type. In your case the easiest is to return an instance of SimpleAuthorizationInfo which implements this interface.
You must initialize the AuthorizationInfo with the roles and/or permissions for the authenticated user. When this method is called, the user is already authenticated but not authorized.
Inside this method you can read the authorization information from any data source that you want, it can be a properties or ini file, properties associated with the user in the LDAP server, a database or anything that pleases you.
A realm implementation could be:
package example.shiro.realm.ldap;
import javax.naming.NamingException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.ldap.JndiLdapRealm;
import org.apache.shiro.realm.ldap.LdapContextFactory;
import org.apache.shiro.subject.PrincipalCollection;
public class JndiLdapAuthzRealm extends JndiLdapRealm {
private List<String> getRoles(String userName) {
List<String> roles = new ArrayList<>();
// TODO: get roles from data source and fill list
roles.add("user");
roles.add("admin");
return roles;
}
private List<String> getPermissions(String userName) {
List<String> perms = new ArrayList<>();
// TODO: get permissions from data source and fill list
perms.add("myapp:run");
perms.add("myapp:file:create");
return perms;
}
#Override
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals,
LdapContextFactory ldapContextFactory) throws NamingException {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
String userName = principals.getPrimaryPrincipal().toString();
info.addRoles(getRoles(userName));
info.addStringPermissions(getPermissions(userName));
return info;
}
}
In your case, rewrite the getRoles and getPermissions to get the roles and permissions for the authenticated user from the properties or ini file.
In shiro.ini:
[main]
ldapRealm = example.shiro.realm.ldap.JndiLdapAuthzRealm
ldapRealm.userDnTemplate = uid={0},cn=users,cn=accounts,dc=example,dc=com
ldapRealm.contextFactory.url = ldap://192.168.0.10

Getting Twitter Access Secret using DotNetOpenAuth in MVC4

I'm creating an app with MVC4 that will authorize users using Twitter and lets them tweet from the app as well. I'm able to get the user authenticated without a problem using the BuiltInOAuthClient.Twitter that is in MVC4. http://www.asp.net/web-pages/tutorials/security/enabling-login-from-external-sites-in-an-aspnet-web-pages-site
I have the access token, and oauth_verifier, but I need to get the acess_secret back from Twitter as well. https://dev.twitter.com/docs/auth/implementing-sign-twitter
What I'm missing is how to pass the oauth_verifier back to Twitter to get the access secret using OAuthWebSecurity.
Again, I can use Twitter for the login ok, but I need to be able to use twitter as the user as well. I've done this with the TweetSharp library before, but am trying to use DotNetOpenAuth on this project.
UPDATE:
I'm using the OAuthWebSecurity class as described in the first link to manage authentication. OAuthWebSecurity.RegisterClient in the AuthConfig expects a DotNetOpenAuth.AspNet.IAuthenticationClient. You can't swap that out with the TwitterConsumer class as suggested.
I can use the "built in" DotNetOpenAuth authentication piece as described in the first link, OR I can use custom code to do the full authorization, but I'm trying to find a way to do both.
I can do it separately, but then the user is presented with the Twitter dialog twice (once to login and once to authorize). I'm hoping there's a way to use the already wired up authentication piece that uses OAuthWebSecurity but ad the authorization piece as well.
I've been banging my head against a wall with this for a few days now, but I finally have something that works. Would be interested to know if it's a valid solution though!
First off, create a new OAuthClient:
public class TwitterClient : OAuthClient
{
/// <summary>
/// The description of Twitter's OAuth protocol URIs for use with their "Sign in with Twitter" feature.
/// </summary>
public static readonly ServiceProviderDescription TwitterServiceDescription = new ServiceProviderDescription
{
RequestTokenEndpoint =
new MessageReceivingEndpoint(
"https://api.twitter.com/oauth/request_token",
HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
UserAuthorizationEndpoint =
new MessageReceivingEndpoint(
"https://api.twitter.com/oauth/authenticate",
HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
AccessTokenEndpoint =
new MessageReceivingEndpoint(
"https://api.twitter.com/oauth/access_token",
HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
};
public TwitterClient(string consumerKey, string consumerSecret) :
base("twitter", TwitterServiceDescription, consumerKey, consumerSecret) { }
/// Check if authentication succeeded after user is redirected back from the service provider.
/// The response token returned from service provider authentication result.
protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response)
{
string accessToken = response.AccessToken;
string accessSecret = (response as ITokenSecretContainingMessage).TokenSecret;
string userId = response.ExtraData["user_id"];
string userName = response.ExtraData["screen_name"];
var extraData = new Dictionary<string, string>()
{
{"accesstoken", accessToken},
{"accesssecret", accessSecret}
};
return new AuthenticationResult(
isSuccessful: true,
provider: ProviderName,
providerUserId: userId,
userName: userName,
extraData: extraData);
}
}
The important part is where you cast the response to an ITokenSecretContainingMessage. It appears that the response has the TokenSecret all along, but it is only on an internal property. By casting it, you get access to a public property. I can't say that I'm a fan of doing this, but then I also don't understand why DotNetOpenAuth the Asp.Net team have hidden the property in the first place. There must be a good reason.
You then register this client in AuthConfig:
OAuthWebSecurity.RegisterClient( new TwitterClient(
consumerKey: "",
consumerSecret: ""), "Twitter", null);
Now, in the ExternalLoginCallback method on the AccountController, the accessSecret is available in the ExtraData dictionary.
The DotNetOpenAuth.AspNet.Clients.TwitterClient class only allows authentication, not authorization. So you wouldn't be able to post tweets as that user if you use that class.
Instead, you can use DotNetOpenAuth.ApplicationBlock.TwitterConsumer, which does not share this limitation and you can even copy the source code for this type into your application and extend it as necessary.
You should be able to enhance the TwitterConsumer class (once you've copied it into your own project) to implement the required interface so that the OAuthWebSecurity class will accept it. Otherwise, you can just use TwitterConsumer directly yourself to both authenticate and authorize your web app so the user only sees Twitter once but you get all the control you need. After all, folks using ASP.NET have been using TwitterConsumer to both login and authorize for subsequent calls to Twitter for long before OAuthWebSecurity even existed.
For a WebForms project template which references Microsoft.AspNet.Membership.OpenAuth in AuthConfig.cs instead of Microsoft.Web.WebPages.OAuth (MVC4 Internet Application) I was able to modify Paul Manzotti's answer to get it to work:
Create a custom twitter client class that derives from DotNetOpenAuth.AspNet.Clients.TwitterClient
public class CustomTwitterClient : TwitterClient
{
public CustomTwitterClient(string consumerKey, string consumerSecret) :
base(consumerKey, consumerSecret) { }
protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response)
{
//return base.VerifyAuthenticationCore(response);
string accessToken = response.AccessToken;
string accessSecret = (response as ITokenSecretContainingMessage).TokenSecret;
string userId = response.ExtraData["user_id"];
string userName = response.ExtraData["screen_name"];
var extraData = new Dictionary<string, string>()
{
{"accesstoken", accessToken},
{"accesssecret", accessSecret}
};
return new AuthenticationResult(
isSuccessful: true,
provider: ProviderName,
providerUserId: userId,
userName: userName,
extraData: extraData);
}
}
Add the custom client in AuthConfig.cs
public static void RegisterOpenAuth()
{
OpenAuth.AuthenticationClients.Add("Twitter", () => new CustomTwitterClient(
consumerKey: ConfigurationManager.AppSettings["twitterConsumerKey"],
consumerSecret: ConfigurationManager.AppSettings["twitterConsumerSecret"]));
}
Ta-dow! Now you can haz access secret.
You can extract the oauth_token_secret from OAuthWebSecurity by designing your own TokenManager. You can register the token manager when you register your Twitter client in OAuthWebSecurity.RegisterClient.
I used this method to extract the needed values to be able to bypass the authorization step of the Linq-to-Twitter lib.
I will soon post my solution at my blog.