/** * */ package cn.bran.play; import java.util.Map; import cn.bran.japid.template.AuthenticityCheck; import cn.bran.japid.util.StringUtils; import play.api.libs.Crypto; import play.data.Form; import play.mvc.Http.Session; /** * add authenticity token check in form binding * * @author bran * */ public class AuthenticForm<T> extends Form<T> { private Class<T> formType; public AuthenticForm(Class<T> clazz) { super(clazz); this.formType = clazz; } /** * @param name * @param clazz */ public AuthenticForm(String name, Class<T> clazz) { super(name, clazz); this.formType = clazz; } private void checkAuthenticity(Map<String, String> data) { AuthenticityCheck anno = this.formType.getAnnotation(AuthenticityCheck.class); Session session = play.mvc.Http.Context.current().session(); String atoken = session.get(AuthenticityCheck.AUTH_TOKEN); session.remove(AuthenticityCheck.AUTH_TOKEN); String uuid = data.get(AuthenticityCheck.AUTH_TOKEN); if (anno != null) { if (StringUtils.isEmpty(uuid) || StringUtils.isEmpty(atoken)) { alarm(); } else { match(atoken, uuid); } } } private void match(String atoken, String uuid) { String sign = Crypto.sign(uuid); if (!sign.equals(atoken)) { alarm(); } } private void alarm() { throw new SecurityException("The form submission does not have a proper authenticity token"); } /* * (non-Javadoc) * * @see play.data.Form#bind(java.util.Map, java.lang.String[]) */ @Override public Form<T> bind(Map<String, String> data, String... allowedFields) { checkAuthenticity(data); return super.bind(data, allowedFields); } }